[英]Malloc Error Caused by Realloc
我已经为此努力了好几个小时。 我正在运行带有XCode 5的Mac OS X 10.8,但出现了以下错误:
malloc: *** error for object 0x1006487b8: incorrect checksum for freed object - object was
probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
不幸的是,此时object 0x1006487b8
已被释放,并且我的调试器无法回忆那里的内容。
问题是,该错误永远不会在同一位置发生。 我只能假设一点内存没有被正确释放,然后计算机尝试将其用于其他目的并最终造成混乱。
我的代码使用的是SDL 2,据我所知,唯一类似于free
的函数调用以以下形式发生,并带有realloc
:
static LGC_Gate* LGC_CreateEmptyGate(){
if (!gates) {
gates = malloc(sizeof(LGC_Gate));
if (!gates)
return NULL;
}
else{
LGC_Gate* tmpgates = realloc(gates, sizeof(LGC_Gate) * (numgates + 1));
if (tmpgates)
gates = tmpgates;
else
return NULL;
}
numgates++;
gates[numgates - 1].id = numgates - 1;
return &(gates[numgates - 1]);
}
gates
是指向gates数组的静态文件范围指针,并在文件顶部声明为:
static LGC_Gate* gates = NULL;
numgates
在文件开头被初始化为零,并表示当前正在使用的门数。 gates
的大小应始终为numgates * sizeof(LGC_Gate)
。
我的计划是将用户创建的所有门都保存在一个阵列中,这样可以很容易地对它们进行汇总,并立即得到通知。 像这样使用LGC_CreateEmptyGate
函数,例如:
LGC_Gate* LGC_InitActGate(LGC_Action act, uint8_t innum, uint8_t outnum){
LGC_Gate* product = LGC_CreateEmptyGate();
if (!product)
return NULL;
product->rule.type = LGC_FUNCTION;
product->rule.act = act;
product->input.used = innum;
product->input.val = 0;
product->output.used = outnum;
product->output.val = 0;
int i;
for (i = 0; i < 8; i++) {
product->inputfrom[i].active = 0;
}
return product;
}
我做错了什么吗?
我已经使用以下代码进行了一些调试:
printf("%d\n", sizeof(LGC_Gate));
LGC_Gate* TestGates[5];
//Go through the gates, initialize each of them, record the value of their ptr,
//and if any are LESS than sizeof(LGC_Gate) apart, report an error.
int gcount;
for (gcount = 0; gcount < 5; gcount++) {
TestGates[gcount] = LGC_InitActGate(LGC_NOR, 2, 1);
printf("%p\n", TestGates[gcount]);
if (gcount < 4) {
if (TestGates[gcount] + sizeof(LGC_Gate) > TestGates[gcount + 1]) {
printf("Error!");
//TestGates[gcount + 1]->id = 4; If this line were uncommented,
// BAD_ACCESS ensues.
}
}
}
令我完全惊讶的是,这实际上输出了一个错误,并且确实在某些指针上崩溃了。 更正:错误的指针始终似乎是第三个指针。 请注意, LGC_InitActGate
调用一次LGC_InitEmptyGate
,并在剩余LGC_InitEmptyGate
简单地复制数据。 到底是怎么回事?
好吧,我相信我现在已经发现了错误。 每次调用realloc时,整个内存块可能会或可能不会重定位,这使我拥有的5个指针数组无效,并指向旧的,已释放的内存。 完全有道理,但这只是一个heckuva错误。 我之前应该注意到。 我不确定如何解决此问题,但感谢您的帮助。
该错误告诉您,系统将尝试分配一些内存,但是当它进入其空闲池时,下一个可用块似乎已损坏。
void* p = malloc(100);
free(p);
strcpy(p, "How do you like these apples, malloc?";
p = malloc(100); // <-- crash may happen here, depending on how the free list works.
通常情况下,碰撞的位置只是检测而已,而不是原因。
有时您可以像这样查找崩溃的一种方法是查看地址上的数据(很幸运,并且可以识别字符串或众所周知的值)。
否则,是时候打破valgrind了。
每次从main
调用realloc
,内存块可能会或可能不会重定位,这会使数组TestGates
拥有指向无效内存的元素。
该代码对我来说看起来不错,尽管可以简化代码,因为您实际上不需要特殊化启动条件。 [注1]
您确定您没有坚持使用代码中某个“门”的指针吗? 您必须非常小心自动重新分配向量,尤其是可能在函数中修改的全局向量:
LGC_Gate* product = LGC_CreateEmptyGate();
some_innocuous_looking_function(); // Oops, this function calls CreateEmptyGate
product->output.val = some_value;
注1:根据Posix realloc规范 :
如果ptr是一个空指针,则对于指定的大小,realloc()将等效于malloc()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.