1

我的功能如下:

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)失败。中止

奇怪的是,相同的函数在终止之前多次成功执行。那么错误是否可能发生在其他地方?因为即使 valgrind 也没有显示任何错误。可能是什么问题呢?

4

3 回答 3

3

这强烈地闻起来像是在调用malloc().

然后损坏的内存管理数据使此调用malloc()失败。

我强烈建议使用 Valgrind 之类的内存检查器运行程序,直到故障被重现。

于 2013-09-07T13:31:36.557 回答
1

这很可能表明堆损坏。

这个函数有一些奇怪的地方。例如,next新节点的字段未初始化。为什么?(甚至没有提到其他领域。)

此外,temp_ldb1->next==NULL检查if看起来过度,因为前面的while循环已经确保它在那个时候是空的。

PS 其作者sYSMALLOc使用了一种相当糟糕的编程实践来编写超复杂的断言条件。现在我们无法确定哪个特定的子条件失败了。

于 2013-09-08T05:33:14.283 回答
1

内存越来越损坏。您可能想尝试一些简单的事情。

1) 在 Insert_ldb 中放置一个计数器。希望程序在相同的计数器值处失败。如果是这样,它可能会使调试更容易。

2) 向 malloc 添加几个字节的填充,例如从 8 个字节开始。

3) 用 malloc 获取内存后初始化内容通常是个好主意。

#define PAD_BYTES       8

void Insert_ldv(int t)
{
    static int counter;
    struct node_ldb *temp_ldb1, *lastnode_ldb;

    counter++;
    printf("counter = %d\n", 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 和 object 如何设置?我猜测该对象的数据项可能比为其分配的内存多,因此它正在覆盖和破坏堆。

另外,什么时候释放内存?

于 2013-09-08T05:22:53.693 回答