문제

I'm writing a function in C that takes in a linked list and a predicate and returns an array containing all values of the linked list satisfying this condition. Here's the function:

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;
}

I passed in a predicate that returns 1 always (i.e. get_all_that is basically to_array), and I'm getting an error at the starred line on the iteration where i=4. The error on the backtrace (which was automatically printed from a SIGABRT) is "*** glibc detected *** ~/list/test: realloc(): invalid next size: 0x0804c0e8 ***"

I opened up GDB telling it to break right before calling realloc when i=4. I then tried calling realloc(vals, i*vps) manually from GDB and got the error message: "Inconsistency detected by ld.so: dl-minimal.c: 138: realloc: Assertion `ptr == alloc_last_block' failed! "

Anyone know what's going on?

도움이 되었습니까?

해결책

Your realloc is allocating one too few elements. Try replacing i by i+1. You should also check for failure of realloc before replacing the pointer you passed to it, since otherwise you will get a memory leak (not to mention crash since you fail to check for NULL) on failure, and removing the unnecessary and ugly casts from the return value of realloc would be nice too.

다른 팁

And your first realloc calls the length with 0, which is a free. So the advice to put i+1 is doubly important.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top