#c #memory #malloc #realloc
Вопрос:
У меня есть очень простой вопрос о выделении памяти в C. Если я напишу:
int* test;
test = malloc(5 * sizeof(int));
test[0] = 1;
test[1] = 2;
test[2] = 3;
test[3] = 4;
test[4] = 5;
test = realloc(test, 6 * sizeof(int));
Я могу использовать перераспределение. Если я определяю тест как:
int test[5] = {1,2,3,4,5};
Я не могу перераспределить его.
В чем разница на более низком уровне между этими утверждениями? Могу ли я как-то перераспределить средства на тест[5]? Как мне пройти бесплатный тест[5]?
Я не уверен, где искать ответ, если бы вы могли связать ресурс, я был бы благодарен.
Комментарии:
1. Потому
realloc
что может работать только с динамически выделяемой памятью. Второй-нет (он либо статический, либо автоматический — в зависимости от контекста)2. Потому что массивы не являются указателями.
3. массивы имеют фиксированное положение.. перераспределение дает вам указатель, который может указывать на другой адрес
4. «Как мне пройти бесплатный тест[5]?» Вы не. Вы не выделили его, поэтому вы не можете освободить его. Компилятор выделил его, и выделенная компилятором память никогда не освобождается.
5. Одним исключением является использование гибкого элемента массива в качестве последнего элемента в a
struct
. Для структуры выделяется память, включающая необходимую длину массива.
Ответ №1:
Вы не можете использовать realloc()
int test[5]
, потому что это test
не указатель, выделенный с помощью функций управления памятью (например malloc()
), и не NULL
.
Цитата из N1570 7.22.3.5 Функция перераспределения:
Если ptr является нулевым указателем, функция перераспределения ведет себя как функция malloc для указанного размера. В противном случае, если ptr не соответствует указателю, ранее возвращенному функцией управления памятью, или если пространство было освобождено вызовом функции free или realloc, поведение не определено. Если память для нового объекта не может быть выделена, старый объект не освобождается и его значение остается неизменным.
Вы не можете выполнить перераспределение int test[5]
. (По крайней мере, стандартного способа нет, но я не могу сказать, что нет расширенного компилятора, который это поддерживает).
Чтобы освободить int test[5]
, выйдите из блока, в котором это объявлено, если это локальная переменная. Такая переменная имеет автоматическую продолжительность хранения и освобождается при выходе из блока. Если это глобальная (или статическая локальная) переменная, выйдите из процесса, и ОС освободит память, используемую процессом.
Комментарии:
1. Спасибо, если я определю тест [5] в функции, память освободится, если она вернется?
2. @AntonHinneck Абсолютно. Все переменные, объявленные внутри функций (если они не определены
static
), автоматически освобождаются при возврате функции.
Ответ №2:
Вы не можете изменить размер, потому что тип test
in int test[5] = {1,2,3,4,5};
есть int[5]
. Число 5
является частью его типа, и объекты в C не могут изменять тип после создания.
В int* test;
, test
это указатель, и он может указывать на область памяти произвольного числа последовательных int
s.
Комментарии:
1. Спасибо, в этом есть полный смысл.
2. Вновь выделенная часть возвращаемой памяти
realloc()
не инициализируется.