В языке C массивы не передаются в функции по значению. Если передать массив как аргумент, в функцию реально поступает указатель на первый элемент массива. Это приводит к тому, что функция модифицирует исходный массив, а не его копию.
Например:
void fillArray(int arr[], int n) { for (int i = 0; i < n; ++i) arr[i] = i*i; } int main() { int myarr[5]; fillArray(myarr, 5); // ok }
Внутри функции:
sizeof(arr) — это вернет размер указателя, а не массива.Работать правильно и безопасно с массивами можно так:
const int *arr.Вопрос: Возможно ли узнать размер исходного переданного массива внутри функции по аргументу
int arr[]черезsizeof(arr)?
Ответ: Нет, нельзя! sizeof(arr) внутри функции вернет размер указателя на тип (например, 4 или 8 байт), а не размер массива.
Пример:
void f(int arr[]) { printf("%zu ", sizeof(arr)); // размер указателя, не массива! } int main() { int x[10]; f(x); // Обычно выведет 8 (x86_64) или 4 (x86) }
История
В промышленном проекте функции копирования массивов пытались вычислять длину массива на лету, используя
sizeof(arr)/sizeof(int)внутри функции. На бою это приводило к копированию только части массива, потому что размер всегда равнялся 1 (8/8), а данные затирались непредсказуемым образом.
История
В одном сетевом приложении функция отправки данных принимала буфер в виде массива без явного указания его размера, из-за чего весь буфер не успевал отправляться, либо вне границ массива происходили чтения мусора, что вызывало ошибки передачи и нестабильность соединения.
История
При написании библиотеки для работы с изображениями программист не снабдил функцию раскрашивания массива изображений обязательным параметром размера. Это привело к переполнению буфера и краху программы на определённых входах, что обнаружилось только в интеграционном тесте на большом изображении.