malloc'ing 和 realloc'ing 指针导致内存泄漏 return

malloc'ing and realloc'ing pointers causing memory leaks on return

我被告知要编写一个包装器,它采用位置的起始地址和大小的数字 'n'。以后用这个内存存点东西。 我能够编写代码,但程序中存在内存泄漏。 这是程序:

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

int alloc_func(char *newptr, int size)
{
    newptr = (char *)realloc(newptr, size);
    printf("In func: %p\n", newptr);
    if(NULL == newptr)
        return 0;
    else
        return 1;
}

int main(int argc, char **argv)
{
    char *foo = "Computer";  //string to be copied to newly allocated memory

    char *ptr = (char *)malloc(1*sizeof(char));
    printf("Before return: %p\n", ptr);
    int size = 10, flag;

    flag = alloc_func(ptr, size);

    printf("After return: %p\n", ptr);

    if(flag == 0)
        return EXIT_FAILURE;
    else{
        strcpy(ptr, foo);
    }

    printf("The copied string is: %s\n", ptr);

    free(ptr);

    return 0;

}

在 运行 valgrind 上,泄漏摘要说 "definitely lost: 10 bytes in 1 block"

发生这种情况是因为我将 ptr(起始地址)作为指针值发送给函数,因此函数正在创建指针的副本,即程序中的 newptr。这个 newptr 被重新分配到 10 个位置。由于我不返回 newptr,一旦函数结束,我的“重新分配”位置将超出范围并丢失。

我的疑问是:

a) 即使创建了指针的副本,ptr 和 newptr 也会指向相同的内存位置,那为什么会泄漏?

b) 不是 malloc 变量 'global' 吗?

c) 发生泄漏是因为我没有传递指针的地址以便不会创建副本吗? (我试过了,但我想知道为什么)

d) 在我的 main 中,什么是免费的(然后 ptr 在做什么)?只是清除为 1 分配的 ptr?

e) 有什么方法可以检查这 10 个“大小”字节的分配是否成功?

您的 alloc_func() 方法应该是:

int alloc_func(char **newptr, int size)
{
    char *p = (char *)realloc(*newptr, size);
    printf("In func: %p\n", p);
    if(NULL == p) {
        return 0;
    } else {
        *newptr = p;
        return 1;
}

然后用

调用它
flag = alloc_func(&ptr, size);

这样 ptr 就会改变。

您正在更改 alloc_funcnewptr 的值。然而,这只是局部变化。它不会更改调用函数中指针的值。结果,你有一个悬空指针和内存泄漏。

调用函数有悬空指针。
alloc_func 有内存泄漏。

您需要 return 从 alloc_func 到调用函数的新分配指针。您可以通过 returned 值或将参数更改为指向指针的指针来实现。

方案一:Return一个指针

char* alloc_func(char *newptr, int size)
{
    newptr = (char *)realloc(newptr, size);
    printf("In func: %p\n", newptr);
    return newptr;
}

并将 main 中的调用更改为:

ptr = alloc_func(ptr, size); // not flag = ...

解决方案 2:更改参数类型

int alloc_func(char **newptr, int size)
{
    *newptr = (char *)realloc(*newptr, size);
    printf("In func: %p\n", *newptr);
    if(NULL == *newptr)
        return 0;
    else
        return 1;
}

并将 main 中的调用更改为:

flag = alloc_func(&ptr, size); // Use &ptr, not ptr