Какое содержимое памяти только что выделено функцией malloc()?
Мне было интересно, что именно держит указатель после malloc()
был использован для выделения памяти? Manpage говорит мне, что calloc()
инициализирует выделенное пространство памяти с нуля.
Функция malloc() распределяет байты размера и возвращает указатель на выделенную память. Память не инициализирована. Если size равен 0, то malloc() возвращает либо NULL, либо уникальное значение указателя, которое впоследствии может быть успешно передано free().
а также
Функция calloc() выделяет память для массива элементов nmemb размером каждый в байтах и возвращает указатель на выделенную память. Память установлена на ноль. Если nmemb или size равен 0, тогда calloc() возвращает либо NULL, либо уникальное значение указателя, которое впоследствии может быть успешно передано free().
Я создал очень короткий пример программы на C, для C(хаха) для себя:
int main() {
char *dynamic_chars;
unsigned amount;
printf("how much bytes you want to allocate?\n");
scanf("%d", &amount);
dynamic_chars = (char*)malloc(amount*sizeof(char));
printf("allocated:\n%s\n", dynamic_chars);
free(dynamic_chars);
return 0;
}
Однако при выполнении этого кода он просто ничего не выводит. Если я инициализирую память самостоятельно, например, инициализирую каждый байт 0xFFFF
используя цикл, программа покажет мне именно то, что я ожидаю. Пространство памяти фактически существует, так как я не получу ошибку, утверждающую, что я пытаюсь получить доступ к неинициализированным переменным или около того.
Поскольку пространство памяти обычно не удаляется, а помечается как перезаписываемое, мне интересно, сможет ли я при выполнении моей программы видеть случайные ранее использованные байты памяти? Но я ничего не увижу, поэтому я действительно смущен тем, как именно malloc()
работает.
EDIT1
Еще одна вещь о malloc()
или, возможно, использование памяти в целом, что интересно в моей программе: если я использую calloc()
Чтобы выделить память, я могу отслеживать фактическое использование памяти моей программой, например, отслеживая ее. Например, если я скажу своей программе, чтобы выделить 1.000.000.000 байт памяти на calloc()
В системном мониторе я увижу следующее: calloc() code">
Как вы можете себе представить, при использовании malloc()
Я ничего не увижу. Я понимаю, что просто выделяя память, я на самом деле не использую ее в то время, но я все еще не понимаю, почему моя операционная система (Unix производная) не распознает ее как используемую. поскольку malloc()
как calloc()
возвращает физический адрес в область памяти, которую я не получаю, так как эта область памяти фактически не зарезервирована ОС. В противном случае я мог видеть это в системном мониторе, верно? Если я хочу опубликовать это как новый вопрос, пожалуйста, дайте мне знать. Но я думаю, так как вопрос все еще о том, как malloc()
работает это вписывается здесь.
3 ответа
Нет, malloc()
возвращает неинициализированную память, содержимое которой является неопределенным. Таким образом, попытка использовать значение вызывает неопределенное поведение.
квотирование C11
, приложение §J.2, Неопределенное поведение
Значение объекта, выделенного
malloc
функция используется
В этом случае, %s
ожидает нулевого завершения char
массив. Тем не менее, содержание dynamic_chars
является неопределенным, так что вполне может вообще отсутствовать нулевой терминатор, который вызовет доступ к внешней памяти, который, в свою очередь, вызывает UB.
квотирование C11
Глава §7.22.3.5, malloc
функция (выделение мое):
malloc
функция выделяет место для объекта, размер которого определяетсяsize
и чье значение не определено.
Тем не менее, пожалуйста, смотрите это обсуждение, почему бы не бросить возвращаемое значение malloc()
и семья в C
,,
Язык Си не определяет, что содержит блок памяти, когда вы его получаете. На практике это, скорее всего, будет просто содержать то, что было в этой физической памяти ранее.
Если память ранее использовалась вашей программой и была освобождена, вы, скорее всего, просто получите то, что было в ней раньше. Если это память, недавно запрошенная из операционной системы, вы получите то, что операционная система поместила в нее. Большинство операционных систем возвращают память, которая была специально установлена в "нулевые" байты, потому что это было бы проблемой безопасности, если бы в памяти все еще содержалось то, что было в ней из какой-то другой программы ранее.
Ничто из этого не гарантируется никакими стандартами, это то, что большинство систем делают на практике.
malloc выделяет память для вас и устанавливает указатель на нее. Он никак не инициализирует память, поэтому выделенная область памяти может содержать что угодно. Поскольку он не содержит строку, вы не можете прочитать ее содержимое, напечатав строку. Вместо этого вы можете распечатать его побайтово, вот так:
for(int i=0;i<amount*sizeof(char);i++)
{
printf("%02x", (unsigned)dynamic_chars[i]);
}