在递归中使用 realloc

发布于 2024-12-05 14:08:26 字数 361 浏览 0 评论 0原文

我可以用 C 语言做这个吗? Valgrind 抱怨 realloc 产生无效的 free?

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

Can I do this in C? Valgrind complains that realloc produces an invalid free?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2024-12-12 14:08:26

是的,它确实会抱怨,因为您作为 mem 传入的 void * 是指针的副本。对函数内指针的更改将不会反映回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;
}

which 输出:

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

并且您可以看到第一个值在 main保留,尽管它在函数内发生了更改。

Yes, it does indeed complain, because the void * you're passing in as mem is a copy of the pointer. Changes to the pointer within the function will not be reflected back to main.

If you want to change mem in the function and have it reflected back, you need to pass a pointer to a pointer.

The following code illustrates this:

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

which outputs:

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

and you can see that the first value is retained in main despite it being changed within the function.

剩余の解释 2024-12-12 14:08:26

任何使用的代码

x = realloc(x, size);

都可能泄漏,除非其他一些变量也保存 x 的当前值。

原因是,如果重新分配失败,返回值为 NULL,因此当前“未调整大小”的内存块将丢失。

此外,在您的代码中,您将

  1. 未初始化的指针传递给函数,
  2. 函数中完成的任何计算都不会更改 main 看到的变量,
  3. 一旦递归函数返回,就会释放该未初始化的指针

,所以无论您的代码中发生了什么代码是“未定义的行为”。

Any code that uses

x = realloc(x, size);

is potentially leaking unless also some other variable holds the current value of x.

The reason is that if reallocation fails the return value is NULL so the current "unresized" memory block is lost.

In your code moreover you are

  1. passing an uninitialized pointer to the function
  2. any computation done in the function will not alter the variable seen by main
  3. freeing that uninitialized pointer once the recursive function returns

So no matter what happens in your code is "undefined behaviour".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文