Я пытаюсь загрузить массив размером n (пользовательский ввод) со случайными значениями.Я читал, что вы не можете вернуть массив в C, вы должны использовать указатель (что весьма запутанно).
Да, связь между указателями и массивами и удивительно широкий круг вещейВы не можете делать с самими массивами являются общими точками путаницы.В какой-то степени это педантичное различие.Почти все C позволяет вам делать с массивом, это делает вас через указатель, но он автоматически преобразует значения типа массива в соответствующие указатели, так что эти детали в значительной степени скрыты.
Но в некоторых местах это высовывается.Например, нет действительного синтаксиса, который позволяет вам даже пытаться объявить функцию, которая возвращает массив.
В других местах он активно вводит в заблуждение.Например, вы можете объявить функцию, которая появляется , чтобы принять массив в качестве аргумента, но стандарт явно указывает, что аргумент на самом деле является соответствующим указателем (и это то, что естественно выпадает, когда вы вызываете такую функциютем не мение).В частности:
int foo(int x[3]);
на 100% эквивалентно
int foo(int *x);
Однако я читал, что если вы сохраняете этот массив в локальной переменной в возвращаемой функции,указатель не будет работать
Дело не только в массивах, а в автоматических переменных в целом.Они логически перестают существовать, когда выходят из области видимости - в конце самого внутреннего блока, в котором они объявлены, - поэтому указатели на или на такие объекты больше не действительны после возврата из функции.Один из способов получить такое значение указателя - функция должна его вернуть.Это само по себе нормально, но вы не можете безопасно разыменовать такое значение указателя.
и статический массив можно использовать (может ли он быть возвращен в функции?).
Время жизни статических переменных любого типа - это полное выполнение программы.Следовательно, это безопасно и может иметь смысл возвращать указатель (in) на статическую переменную из функции.Но хотя он может работать, чтобы возвращать указатель на статический массив из вашей функции, вы все равно не можете вернуть сам такой массив.
Кроме того, я прочитал, что после использования вы должны вызывать freeмассив открыт, пространство резервной копии?
Вы должны освободить память, выделенную для вас одной из функций выделения памяти (malloc()
и т. д.), и никакой другой.Но когда вы выделяете память внутри функции, вы можете поручить вызывающей стороне освободить эту память, возвращая указатель на нее, среди других способов.
На самом деле, большинство из того, что вы демонстрируете в своем примере кода, в порядке.в этом отношении.Однако вы делаете ключевую ошибку, которая подрывает вашу программу.Здесь:
int *a = (int*)malloc(input);
Вы выделяете input
байт и сохраняете указатель на них в a
, но этого недостаточно для input
объекты типа int
.Размер int
варьируется от реализации к реализации, но минимальный размер, разрешенный стандартом, составляет два байта, в наиболее распространенном размере - четыре байта.Чтобы выделить место для input
объектов типа int
, основной идиомой является
int *a = malloc(input * sizeof(int));
Лично я предпочитаю
int *a = malloc(input * sizeof(*a));
, потому что тогда я получу правильный размер noНеважно, к какому типу относится ссылочный тип указателя, и даже если я изменю его позже.
Тот факт, что вы обработали выделенное пространство так, как если бы оно было больше, чем на самом деле, вероятно, объясняет большую часть неправильного поведения вашей программы, включаясбой при попытке освободить выделенную память.