2009-11-06 87 views
1
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()这是否使用C指针可以防止泄漏内存?

回答

0

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

1

没有问题—其实,这是分配函数返回—但你可能要free()内存当你用它完成后,将仍然使用的内存的正确方法。八个字节不会成为问题,但针对内存泄漏进行编码是一个很好的习惯。

+1

+1即使你错过了从void void()中返回值的问题(我也几乎错过了,并且@Ed击败了我们所有人)。 – 2009-11-06 21:49:08

+0

Ack - 好赶上! – 2009-11-06 21:51:57

0

只要你记得释放x指向的内存,那么你将不会有任何问题。通过使用malloc(),您可以在堆回到调用函数时独立分配内存。

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

+ 1为了让我从“void”函数返回而获得胜利,但是,为什么不只是'a'返回'char *'?这会容易得多(并且对于像C这样怀疑OP的人来说,对于新来的人来说可能会更容易混淆)。 – 2009-11-06 21:50:20

+0

是的,我不确定是否应该包括那部分。我编辑帖子说原来的方式没问题,这是完成同样任务的另一种方法。 – 2009-11-06 21:52:34

1

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

只要确保将free()分配给内存即可。

3

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

您不在malloc中检查成功或函数调用。不要忘记错误处理。

+0

+1,因为我也忘记了错误处理。 – 2009-11-06 21:54:50

+0

实际上*有*代码的某些问题(错误的返回类型),但用于检查malloc的内存+1。 – Francesco 2009-11-06 21:56:10

+0

+1,因为我也忘了检查malloc返回的内容。 – 2009-11-06 22:07:02

1

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

总而言之,分配内存并将其传回给调用者通常是一个错误。

最好是期望内存由调用者分配,因为如果他们分配内存,他们会记住释放内存并正确执行。

+2

这不是OP代码的问题,它是OP代码(虚构)用户的问题。如果你是C程序员,你记得'free()'内存。期。任何不了解内存管理的人,不会阅读关于他们完成“释放()”所需内存的文档时不知道C. – 2009-11-06 21:58:47

+1

是的,我同意克里斯。这是C,而不是C++。 – 2009-11-06 22:00:57

+0

@Ed - Ouch。这对C++程序员来说有点苛刻。不是说这不一定是真的... – 2009-11-06 22:07:03

0

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

+0

如果它是函数中的局部变量,函数返回时它将从堆栈中消失。但是如果你把它分配在堆上(ala malloc()等),尽管指向它的指针会随着堆栈帧丢失,但是如果你在返回之前没有释放()它,分配的内存将会持续存在。当然,在这个例子中,因为你正在返回一个指向它的指针,所以调用函数可以保持内存的句柄。 – 2009-11-06 23:06:38