malloc обнуляет память?

Учитывая этот код C, скомпилированный с gcc 4.3.3

#include <stdio.h>
#include <stdlib.h>


int main(int argc, char * argv[])
{

    int * i;

    i = (int *) malloc(sizeof(int));

    printf("%d\n", *i);
    return 0;

}

Я ожидаю, что на выходе будет то, что было в памяти, которую возвращает malloc(), но вместо этого на выходе будет 0. Обнуляет ли malloc память, которую он возвращает? Если да, то почему?


person endeavormac    schedule 25.10.2009    source источник
comment
То, что вы ожидаете, имеет место. Он выводит все, что было в памяти, которую возвращает функция malloc(), которая оказалась равной нулю.   -  person David Schwartz    schedule 30.08.2011


Ответы (6)


malloc сама по себе не обнуляет память, но многие операционные системы обнуляют память, которую ваша программа запрашивает из соображений безопасности (чтобы один процесс не мог получить доступ к потенциально конфиденциальной информации, которая использовалась другим процессом).

person Robert Gamble    schedule 25.10.2009
comment
Я должен упомянуть, что ничто в стандарте не препятствует обнулению памяти malloc. Для эффективности обычно это не так, но это не обязательно. - person paxdiablo; 26.10.2009
comment
Также обратите внимание, что хотя новая память из ОС может быть обнулена, если ваше приложение повторно использует память, которую оно использовало ранее, скорее всего, не будет обнулено. Так что даже не думайте полагаться на это :) - person bdonlan; 26.10.2009
comment
Совершенно верно, бдонлан. Чтобы увидеть этот malloc X байтов, запишите в него некоторую информацию, освободите его, затем снова malloc X байтов и прочитайте его. Вероятно, это будут те же данные. - person Zan Lynx; 16.03.2011
comment
В режиме отладки malloc обычно обнуляет память. Убедитесь, что вы компилируете в режиме выпуска. - person Yochai Timmer; 05.02.2012
comment
@YochaiTimmer: Хорошие отладочные mallocs заполняют память защитным значением, например. VC++2005 использует 0xFD, 0xDD и 0xCD. - person tc.; 12.06.2012

Функция malloc() не устанавливает для выделенной памяти какое-либо конкретное значение. Если вы хотите убедиться, что память равна нулю, используйте calloc() или эквивалент. В противном случае вы получите то, что было раньше (что в вашем случае может быть равно нулю).

person Greg Hewgill    schedule 25.10.2009
comment
Я ожидал бы этого, если бы он не был постоянно равен 0. Почему я должен получать значение, которое постоянно равно 0, снова и снова? - person endeavormac; 26.10.2009
comment
Вы многократно запускаете одну и ту же программу одним и тем же образом и ожидаете разных результатов? Хотя сам malloc() не гарантирует обнуление памяти, ОС выполняет ту же работу, чтобы загрузить вашу программу и запустить ее. Код вашей библиотеки времени выполнения делает то же самое, чтобы настроить динамическую память и начать выполнение вашего кода. Как уже упоминалось в другом ответе, ОС, скорее всего, предоставит вам новые страницы памяти, инициализированные некоторым конкретным значением, чтобы изолировать разные процессы друг от друга. - person Greg Hewgill; 26.10.2009
comment
Ваша программа запрашивает свежую память у ОС. ОС обнуляет память, когда она впервые назначается процессу. Попробуйте ввести случайные значения, освободить часть и выделить другую. - person nos; 26.10.2009

Значение в выделенной памяти официально не определено. C99 утверждает: The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate. malloc() может делать все, что захочет, включая обнуление. Это может быть преднамеренным, побочным эффектом реализации, или у вас может быть просто много памяти, которая равна 0.

FWIW на OS X с Apple gcc 4.0.1 Я не могу заставить его выйти не 0, даже выполняя много распределений:

for( idx = 0; idx < 100000; idx++ ) {
    i = (int *) malloc(sizeof(int));
    printf("%d\n", *i);
}
person Schwern    schedule 25.10.2009
comment
Попробуйте установить для *i ненулевое значение, освободить i, затем снова использовать malloc и посмотреть, что получится. - person Stephen Canon; 26.10.2009
comment
Любая память, выделенная вашему процессу в первый раз, будет обнулена по соображениям безопасности, так что вы не сможете выделить память и узнать, какую информацию в нее записал другой процесс. - person gnasher729; 21.01.2015
comment
@ gnasher729 Это может быть то, что делает конкретный компилятор C, но нет гарантии, что это так, и на него не следует полагаться. - person Schwern; 21.01.2015

Malloc не должен заполнять память. Из соображений производительности релизные версии часто ничего не делают с памятью. «Безопасная» библиотека может иметь реализацию malloc, очищающую память. Это зависит от разработчика библиотеки. Есть несколько общих шаблонов, которые заполняются в память различными библиотеками отладки компилятора, to-0xcd-0xdd-etc-on-malloc-free-new">объяснено в этом разделе stackoverflow.

person Adisak    schedule 25.10.2009

Вы определенно не можете полагаться на то, что это 0. malloc больший кусок и сбросить его, чтобы увидеть.

person pixelbeat    schedule 25.10.2009

Является ли это int; интервал = 0; или интервал=00000000; он займет столько же места в памяти. printf часто улавливает первый 0 как завершающий нуль независимо от того, что еще находится в строке. Если вы используете компараторы строк, а 0 является заполнителем, я бы порекомендовал вам использовать ЧТО-НИБУДЬ, кроме 0 для этого заполнителя, поскольку библиотеки на основе строк действительно отстой. Попробуйте F, а затем напишите элемент управления в себе, вставив нулевой термин или новую строку, если это необходимо, это будет более переносимо.

person mistermista    schedule 20.01.2019