返回指向自动变量的指针

And*_*ech 10 c memory-leaks function

假设您具有以下功能:

char *getp()
{
    char s[] = "hello";
    return s;
}
Run Code Online (Sandbox Code Playgroud)

由于函数返回指向要在外部使用的函数中的局部变量的指针,它是否会导致内存泄漏?

PS我还在学习C所以我的问题可能有点幼稚......

[更新]
所以,如果你想要返回一个新char[]数组(即可能是一个子字符串函数),那么你究竟返回了什么?它应该是指向外部变量的指针吗?即一个char[]不是函数本地的?

Meh*_*ari 25

它不会导致内存泄漏.它会引起悬垂的参考.局部变量在堆栈上分配,一旦超出范围就会被释放.因此,当函数结束时,您返回的指针不再指向您拥有的内存.这不是内存泄漏(内存泄漏是指分配一些内存而不释放内存).

[更新]:为了能够返回在函数中分配的数组,您应该将它分配到堆栈外(例如在堆中),如:

char *test() {
    char* arr = malloc(100);
    arr[0] = 'M';
    return arr;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果free在完成使用后没有调用函数中的内存,则会发生内存泄漏.


Tom*_*Tom 13

不,它不会泄漏,因为它在getp()结束后被销毁;

它将导致未定义的行为,因为现在您有一个指向内存区域的指针,该内存区域不再包含您认为它的功能,并且可以被任何人重用.

如果将该数组存储在堆上,而不执行对free()的调用,则会发生内存泄漏.

char* getp(){

   char* p = malloc(N);
   //do stuff to p
   return p;
}

int main(){
    char* p = getp();
    //free(p) No leak if this line is uncommented
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这里,p不会被破坏,因为它不在堆栈中,而是在堆中.但是,一旦程序结束,分配的内存尚未释放,导致内存泄漏(即使它在进程终止后完成).

[UPDATE]

如果要从函数返回新的c-string,则有两个选项.

  • 将它存储在堆中(如上例所示,或者像这个返回重复字符串的真实示例);
  • 传递缓冲参数

例如:

    //doesnt exactly answer your update question, but probably a better idea.
    size_t foo (const char* str, size_t strleng, char* newstr);
Run Code Online (Sandbox Code Playgroud)

在这里,你必须在调用foo函数之前为newstr(可能是堆栈OR堆)分配内存.在这种特殊情况下,它将返回newstr中的字符数量.


Rob*_*ino 8

这不是内存泄漏,因为内存正在正常释放.

但这是一个错误.你有一个指向未分配内存的指针.它被称为悬空参考,是C中常见的错误来源.结果未定义.在尝试使用该指针时,在运行时才会看到任何问题.