Использование realloc в рекурсии - PullRequest
1 голос
/ 20 сентября 2011

Могу ли я сделать это в C?Valgrind жалуется, что realloc выдает недопустимую бесплатную версию?

int main(){
    void* mem;
    // Do stuff
    recurfunc(123, mem);
    // Do stuff
    if(mem)
        free(mem);
    return 0;
}

void recurfunc(int x, void* mem){
     .....
     // Do stuff
     mem = realloc(mem, newsize);
     // Do stuff
     recurfunc(x, mem);
     .....
}

Ответы [ 2 ]

9 голосов
/ 20 сентября 2011

Да, он действительно жалуется, потому что void *, который вы передаете как mem, является копией указателя. Изменения указателя внутри функции будут не отражаться обратно на main.

Если вы хотите изменить mem в функции и отразить его обратно, вам нужно передать указатель на указатель.

Следующий код иллюстрирует это:

#include <stdio.h>
#include <stdlib.h>

static void fn (void *p1, void **p2) {
    p1 = realloc(p1, 200);
    *p2 = realloc (*p2, 200);
    printf ("    In call: %p %p\n", p1, *p2);
}

int main (void) {
    void *x1 = malloc (100);
    void *x2 = malloc (100);
    printf ("Before call: %p %p\n", x1, x2);
    fn (x1, &x2);
    printf (" After call: %p %p\n", x1, x2);
    return 0;
}

который выводит:

Before call: 0x896f008 0x896f070
    In call: 0x896f0d8 0x896f1a8
 After call: 0x896f008 0x896f1a8
                    ^
                    +--- Note this bit.

и вы можете видеть, что первое значение сохраняется в main несмотря на то, что оно было изменено в функции.

4 голосов
/ 20 сентября 2011

Любой код, который использует

x = realloc(x, size);

, может быть утечкой, если только некоторая другая переменная не содержит текущее значение x.

Причина заключается в том, что если перераспределение завершается неудачно, возвращаемое значениеNULL так что текущий «неизмененный» блок памяти теряется.

Более того, в вашем коде вы

  1. передаете неинициализированный указатель на функцию
  2. при любом вычисленииВыполнение в функции не изменит переменную, видимую main
  3. , освобождая этот неинициализированный указатель, когда рекурсивная функция вернет

Так что независимо от того, что происходит в вашем коде, это «неопределенное поведение»».

...