我的函数如下:
void Insert_ldb(int t){
struct node_ldb *temp_ldb1,*lastnode_ldb;
temp_ldb1=root_ldb[t];
while(temp_ldb1->next!=NULL)
temp_ldb1=temp_ldb1->next;
if(temp_ldb1->next==NULL){
lastnode_ldb=malloc(sizeof(*lastnode_ldb));//error appears at this line
temp_ldb1->next=lastnode_ldb;
}
}
结构node_ldb定义为:
struct node_ldb{
int sno;
int *lvar;
int *object;
struct node_ldb *next;
};
编译时没有出现错误,但在执行时终止并显示以下消息:
malloc.c:3096:sYSMALLOc:断言
(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)
失败。 中止
奇怪的是,相同的函数在终止之前成功执行了很多次。那么错误有可能发生在其他地方吗?因为即使是瓦尔格林德也没有显示任何错误。可能是什么问题?
这闻起来很像在此调用malloc()
之前发生的内存管理损坏。
然后,损坏的内存管理数据使此调用失败malloc()
。
我强烈建议使用内存检查器(例如Valgrind)运行该程序,直到重现故障为止。
内存正在损坏。 您可能想尝试一些简单的事情。
1)在Insert_ldb放一个计数器。 希望程序在相同的计数器值下失败。如果是这样,可能会使调试更容易。
2) 向 malloc 添加几个字节的填充,例如从 8 个字节开始。
3)通常最好在之后初始化内容 使用马洛克获取记忆。
#define PAD_BYTES 8
void Insert_ldv(int t)
{
static int counter;
struct node_ldb *temp_ldb1, *lastnode_ldb;
counter++;
printf("counter = %dn", counter);
temp_ldb1 = root_ldb[t];
while (temp_ldb1->next != NULL) {
temp_ldb1 = temp_ldb1->next;
}
if (temp_ldb1->next == NULL){
lastnode_ldb = malloc(sizeof(*lastnode_ldb) + PAD_BYTES);
memset(lastnode_ldb, 0, sizeof(*lastnode_ldb));
temp_ldb1->next = lastnode_ldb;
}
}
当程序没有因填充而失败时,那么您在短期内有一个解决方法。 将PAD_BYTES增加 4 的倍数,直到它不会失败。 工作正常时,PAD_BYTES是内存溢出的字节数。
如何设置lvar和对象? 我猜该对象可能比为其分配的内存有更多的数据项,因此它会覆盖和损坏堆。
另外,内存何时释放?
这很可能表示堆损坏。
这个功能有一些奇怪的事情。例如,新节点的next
文件未初始化。为什么?(甚至没有提到其余的字段。
此外,if
中的temp_ldb1->next==NULL
检查看起来过多,因为前面的while
周期已经确保它在此时为空。
附言该sYSMALLOc
的作者使用了一种相当糟糕的编程实践来编写超复杂的断言条件。现在我们无法弄清楚哪个特定的子条件失败了。