2010-12-13 3 views
1

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

У меня есть две реализации, которые скомпилируются с файлами .a (я буду называть эту программу 1), другие ссылки с общими объектами (я буду называть эту программу 2). Программа 1 скомпилирована с использованием make-файла, предоставленного SCIP, тогда как программа 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 инициализировать память, которую он выделяет. Я просто должен узнать, почему структура инициализируется в скомпилированной реализации и не входит в реализацию общего объекта.

+0

Какая ОС это? – sharptooth

ответ

1

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

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

2

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

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

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

+0

Я немного поработал с кодом и поменял malloc на calloc. После повторного компиляции всего, я получаю такое же поведение, т. Е. Структура SCIP программы 2 все еще не инициализирована. Я еще более смущен. Чтобы уточнить, программа 2 на самом деле является кодом python, вызывая SO, созданный SWIG (генератор интерфейса python-C). Недавно я написал некоторый стандартный C-код для доступа к общим объектам SCIP, удалению Python и SWIG с рисунка, а когда выделен ptr, он снова является «обнуленным» блоком памяти, независимо от того, используется ли malloc или calloc , – Andy

+0

@ Andy Что касается вашего первого момента, это действительно довольно странно. Какой именно вызов 'calloc' вы используете, сразу же после чего структура не равна нулю? – NPE

+0

Это было «ptr = calloc (1, size)», я предполагаю, что это правильно? – Andy

0

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

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

Смежные вопросы