Что может заставить malloc инициализировать память? - PullRequest
1 голос
/ 13 декабря 2010

Я пишу код для использования библиотеки SCIP (решает проблемы оптимизации). Саму библиотеку можно скомпилировать двумя способами: создать набор файлов .a, затем двоичный файл, ИЛИ создать набор общих объектов. В обоих случаях SCIP компилируется с собственным, довольно большим Makefile.

У меня есть две реализации: одна компилируется с файлами .a (я назову эту программу 1), другая - с общими объектами (я назову эту программу 2). Программа 1 компилируется с использованием предоставленного SCIP make-файла, тогда как программа 2 компилируется с использованием моего собственного, намного более простого make-файла.

Поведение, с которым я сталкиваюсь, происходит в коде SCIP, а не в коде, который я написал. Выдержка из кода выглядит следующим образом:

void* BMSallocMemory_call(size_t size)  
{  
   void* ptr;  

   size = MAX(size, 1);  
   ptr = malloc(size);  

   // This is where I call gdb print statements.  

   if( ptr == NULL )  
   {  
      printf("ERROR - unable to allocate memory for a SCIP*.\n");  
   }  
   return ptr;  
}

void SCIPcreate(SCIP** A)  
{  
   *A = (SCIP*)BMSallocMemory_call(sizeof(**(A)))  
   .  
   .  
   .  
}  

Если я отлаживаю этот код в gdb и перехожу на BMSallocMemory_call(), чтобы увидеть, что происходит, и просмотреть содержимое *((SCIP*)(ptr)), я получаю следующий вывод:

Программа 1, вывод gdb:

289    size = MAX(size, 1);  
(gdb) step  
284 {  
(gdb)   
289    size = MAX(size, 1);  
(gdb)   
290    ptr = malloc(size);  
(gdb) print ptr  
$1 = <value optimised out>  
(gdb) step  
292    if( ptr == NULL )  
(gdb) print ptr  
$2 = <value optimised out>  
(gdb) step  
290    ptr = malloc(size);  
(gdb) print ptr  
$3 = (void *) 0x8338448  
(gdb) print *((SCIP*)(ptr))  
$4 = {mem = 0x0, set = 0x0, interrupt = 0x0, dialoghdlr = 0x0, totaltime = 0x0, stat = 0x0, origprob = 0x0, eventfilter = 0x0, eventqueue = 0x0, branchcand = 0x0, lp = 0x0, nlp = 0x0, relaxation = 0x0, primal = 0x0, tree = 0x0, conflict = 0x0, cliquetable = 0x0, transprob = 0x0, pricestore = 0x0, sepastore = 0x0, cutpool = 0x0}  

Программа 2, вывод gdb:

289    size = MAX(size, 1);  
(gdb) step  
290    ptr = malloc(size);  
(gdb) print ptr  
$1 = (void *) 0xb7fe450c  
(gdb) print *((SCIP*)(ptr))  
$2 = {mem = 0x1, set = 0x8232360, interrupt = 0x1, dialoghdlr = 0xb7faa6f8, totaltime = 0x0, stat = 0xb7fe45a0, origprob = 0xb7fe4480, eventfilter = 0xfffffffd, eventqueue = 0x1, branchcand = 0x826e6a0, lp = 0x8229c20, nlp = 0xb7fdde80, relaxation = 0x822a0d0, primal = 0xb7f77d20, tree = 0xb7fd0f20, conflict = 0xfffffffd, cliquetable = 0x1, transprob = 0x8232360, pricestore = 0x1, sepastore = 0x822e0b8, cutpool = 0x0}  

Единственная причина, по которой я могу думать, заключается в том, что в make-файле программы 1 или SCIP есть какая-то опция, которая заставляет malloc инициализировать память, которую она выделяет. Я просто должен понять, почему структура инициализируется в скомпилированной реализации, а не в реализации разделяемого объекта.

Ответы [ 3 ]

2 голосов
/ 13 декабря 2010

Я сомневаюсь, что разница связана с тем, как построены две программы.

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

edit Вы можете найти следующие интересующие вас вопросы в прошлом:

1 голос
/ 13 декабря 2010

Инициализация неправильно выделенной памяти может зависеть от реализации. Реализации свободны не делать этого по соображениям производительности, но они могут инициализировать память, например, в режиме отладки.

Еще одна заметка. Даже неинициализированная память может содержать нули.

0 голосов
/ 13 декабря 2010

В Linux, согласно этой теме , память будет заполнена нулями при первой передаче приложению.Таким образом, если ваш вызов malloc() вызвал рост кучи программы, «новая» память будет заполнена нулями.

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

...