我正在编写代码以使用名为SCIP的库(解决优化问题)。库本身可以用两种方式编译:创建一组.a文件,然后创建二进制文件,或者创建一组共享对象。在这两种情况下,SCIP都是用它自己的,相当大的Makefile编译的。
我有两个实现,一个用.a文件编译(我称之为程序1),另一个用共享对象链接(我称之为程序2)。程序1使用SCIP提供的makefile编译,而程序2使用我自己的,更简单的makefile编译。
我遇到的行为发生在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}
我能想到的唯一原因是,在程序1或SCIP的makefile中,有某种选项迫使malloc初始化它分配的内存。我只需要了解结构在编译实现中初始化的原因,而不是在共享对象实现中。
答案 0 :(得分:2)
我怀疑这两个程序的构建方式有何不同。
malloc
不会初始化它分配的内存。它可能会偶然发生,你得到的记忆充满了零。例如,刚刚启动的程序更有可能从malloc
获得零填充内存,而不是正在运行一段时间并分配/释放内存的程序。
编辑您可能会发现以下过去感兴趣的问题:
答案 1 :(得分:1)
malloc-ed内存的初始化可能依赖于实现。出于性能原因,实现可以自由地不这样做,但是它们可以初始化内存,例如在调试模式下。
还有一点需要注意。即使未初始化的内存也可能包含零。
答案 2 :(得分:0)
在Linux上,根据this thread,当第一次交给应用程序时,内存将被填零。因此,如果您对malloc()
的调用导致程序堆增长,则“新”内存将为零填充。
验证的一种方法当然是从您的例程中将转换为 malloc()
,这应该非常清楚它是否包含直接初始化内存的代码。 / p>