我在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检测到***〜/ list / test:realloc():下一个大小无效:0x0804c0e8 ***”
当i = 4时,我打开GDB告诉它在调用realloc之前中断。然后我尝试从GDB手动调用realloc(vals,i * vps)并得到错误消息:“ld.so检测到不一致:dl-minimal.c:138:realloc:断言`ptr == alloc_last_block'失败! “
任何人都知道发生了什么事?
答案 0 :(得分:2)
您的realloc
分配的元素太少了。尝试将i
替换为i+1
。您还应该在替换传递给它的指针之前检查realloc
的失败,否则您将在失败时获得内存泄漏(更不用说崩溃,因为您未能检查NULL
),并且从realloc
的返回值中删除不必要和丑陋的强制转换也很不错。
答案 1 :(得分:0)
您的第一个realloc
调用长度为0,即free
。因此,提出i+1
的建议非常重要。