Why getLastRow() lies to you
getLastRow() returns the last row that has content anywhere in the sheet. Not in your column. The whole sheet. If column A runs to row 500 and column C stops at row 40, getLastRow() says 500, and your code that wanted the bottom of column C is now off by 460 rows of empty cells. getLastRow lying to you is a rite of passage; everyone meets it once.
The same trap catches getDataRange(), which spans from A1 to the last row and last column with any data. Both functions describe the bounding box of the populated region. Neither one knows or cares that you only asked about one column. There is no built-in getLastRowOfColumn, which is exactly why this question gets asked over and over.
Trailing gaps make it worse. Say column C has values in rows 2-10, then a blank stretch, then a stray value in row 38 someone pasted and forgot. The 'last row with data' is genuinely ambiguous, and you have to decide what you mean: the last non-empty cell (38), or the end of the first contiguous block (10). The script above answers the first. If you want the second, scan downward from the top and stop at the first blank instead.