这种C指针的使用是否可以避免泄漏内存?

时间:2009-11-06 21:42:51

标签: c memory-leaks

char *a() {
    char *t = malloc(8);
    t[0] = 'a'; 
    t[1] = 'b';
    //...
    t[7] = 'h';
    return t;
}

int main(void) {
    char *x = a();
    //do something with x 
    //...
    free(x);
    return 0;
}

此代码是否存在任何潜在问题,因为内存已在a()中分配并用于main()中的内存?

8 个答案:

答案 0 :(得分:10)

首先,a()被声明为返回void,但是您尝试返回char *。更改签名以返回char *。

其次,你的函数很好,但你的示例代码有内存泄漏,因为你永远不会释放返回指针所指向的内存。

第三,正如gbrandt指出的那样,在调用malloc之后,你没有检查是否成功。 malloc可能会失败,并检查它是否是一个很好的习惯。


实现此目的的另一种方法是将指针传递给指向()的指针,然后调用者必须在将指针传递给()之前自己创建指针,但无论哪种方式,您仍然需要释放记忆。说实话,在这种情况下,我会采用你的方法。没有令人信服的理由这样做,只是想我会提到它。

void a(char **p)
{
    *p = malloc(8);
    if (*p)
    {
        **p[0] = 'a'; 
        **p[1] = 'b';
        ...
        **p[7] = 'h';
    }
}

int main(void)
{
    char *x;
    a(&x);
    //do something with x 
    .....
    free(x);
}

如果这种替代方法让您感到困惑,请告诉我,因为我很乐意提供解释(但目前,我需要重新开始工作!)

答案 1 :(得分:3)

以上所有好建议。代码的小问题,最重要的是......

您没有在malloc或函数调用后检查是否成功。不要忘记错误处理。

答案 2 :(得分:1)

没有问题 - 实际上,这是分配在函数返回后仍然可以使用的内存的正确方法 - 但是当你完成使用它时你可能想要free()内存。八个字节不会成为问题,但编码内存泄漏是一个很好的习惯。

答案 3 :(得分:1)

除了a()上的错误返回类型(应该是char *而不是void)之外,代码没有任何问题。

确保free()完成后分配的内存。

答案 4 :(得分:1)

这里的大部分答案表明这不是问题,只需记住稍后释放()。这在技术上是正确的,但实际上是一个问题。无论何时在一个作用域中分配内存并期望它在另一个作用域中释放,您都会要求内存泄漏。人们不记得释放记忆。还有一个问题是调用者必须知道你使用了malloc而不是alloca()或new()或其他东西。如果他们调用除匹配的释放例程之外的任何内容,则结果是未定义的。

简而言之,分配内存并将其传递给调用者通常是错误的。

最好是期望调用者分配内存,因为如果他们分配内存,他们会记得释放它并正确地这样做。

答案 5 :(得分:0)

不,您不会明确地遇到任何问题,因为您在a中分配了该功能并在main中使用它。

答案 6 :(得分:0)

只要你记得释放x所指向的记忆,你就不会有任何问题。通过使用malloc(),您已经在堆上分配了内存,这在返回调用函数时是独立的。

答案 7 :(得分:0)

感谢。我刚刚编辑了代码。我猜这次应该没问题。顺便说一句,在C中,当一个函数完成时,编译器是否清除堆栈中的所有变量(包括数组和指针)?