1

我正在用 C 语言编写一个函数,该函数接受一个链表和一个谓词,并返回一个数组,其中包含满足此条件的链表的所有值。这是功能:

void **get_all_that(list_t *l, int (*pred)(const void *)) {
    void **vals = NULL;
    int i = 0; // Number of matches found
    const size_t vps = sizeof(void *);
    node_t *n = l->first;
    while (n) {
        if (pred(n->value)) {
            vals = (void **)realloc(vals, i*vps); // (*)
            vals[i] = n->value;
            i++;
        }
        n = n->next;
    }
    if (vals != NULL) {
        vals = (void **)realloc(vals, i*vps);
        vals[i] = NULL; // NULL-terminate array
    }
    return vals;
}

我传入了一个始终返回 1 的谓词(即 get_all_that 基本上是 to_array),并且在 i=4 的迭代中的星号行出现错误。回溯上的错误(从 SIGABRT 自动打印)是“*** glibc detected *** ~/list/test: realloc(): invalid next size: 0x0804c0e8 ***”

我打开 GDB 告诉它在 i=4 时调用 realloc 之前立即中断。然后我尝试从 GDB 手动调用 realloc(vals, i*vps) 并收到错误消息:“ld.so 检测到不一致:dl-minimal.c: 138: realloc: Assertion `ptr == alloc_last_block' failed!”

有谁知道发生了什么?

4

2 回答 2

2

realloc分配的元素太少。尝试替换ii+1. 您还应该在替换传递给它的指针之前检查失败realloc,因为否则您将在失败时出现内存泄漏(更不用说崩溃,因为您没有检查NULL),并从返回值中删除不必要和丑陋的强制转换的realloc也会很好。

于 2010-10-05T03:11:23.217 回答
0

你第一次realloc用 0 调用长度,即 a free。所以提出的建议i+1是双重重要的。

于 2010-10-05T05:47:50.403 回答