Указатели и массивы в C связаны, но это не одно и то же:
При передаче массива в функцию фактически передается указатель на первый элемент массива (поэтому sizeof внутри функции не дает размер всего массива, а только размер указателя).
Синтаксис передачи:
void foo(int arr[], int size) { // arr — фактически int* for (int i = 0; i < size; ++i) printf("%d ", arr[i]); } int main() { int data[5] = {1,2,3,4,5}; foo(data, 5); }
Вопрос: Что вернет выражение sizeof(arr) внутри функции, если arr — это параметр типа int arr[]?
Ответ: Возвращает размер указателя (sizeof(int*)), а не размер всего массива. Потому что в функцию передается указатель на первый элемент, информация о длине теряется.
void printSize(int arr[]) { printf("%zu ", sizeof(arr)); // sizeof(int*) обычно 4 или 8 }
История
В коммерческом проекте для вычисления среднего значения в массиве был написан код, где для количества элементов внутри функции брали sizeof(arr) / sizeof(arr[0]), что возвращало всегда 1 или 2 вместо реального количества элементов. Из-за этого программа некорректно работала с данными, некорректно усредняла значения.
История
В одном проекте динамически аллоцированный массив передавался в функцию без отдельного хранения длины (size). В результате функция не знала, сколько выделено элементов, приводило к выходу за границы, утечкам или порче памяти.
История
По ошибке был использован массив фиксированного размера как указатель, и на некоторых компиляторах допускалось прямое присваивание через memcpy целого массива вместо его элементов. Это приводило к неочевидной ошибке, когда терялись части структуры данных или происходил переполнение стека.