在C中:为什么在函数之外存在堆栈分配结构?

时间:2010-02-28 19:11:14

标签: c stack heap-memory

我的职能:

struct hostent * gethost(char * hostname){
    if(/*some condition under which I want 
         to change the mode of my program to not take a host*/){
       return null
    }
    else{
        struct hostent * host = gethostbyname(hostname);
        return host;
    }
}

在main中:

struct hostent * host = gethost(argv[2]);

(忽略代码中的任何小错误,我从内存中喷出)

这很好用。尽管我没有自由,但Valgrind并没有告诉我,我正在失去记忆。

为什么呢?我认为在堆栈上分配的东西会随着函数调用返回而消失?或者是因为我返回指针?这有什么危险吗?

4 个答案:

答案 0 :(得分:10)

没有在堆栈上分配

host,只有指向它的指针在堆栈上。函数返回时会复制指针,因此代码没有任何问题。

请注意,gethostbyname实际上并不动态分配内存。它总是返回一个指向同一个静态分配的内存块的指针,这就是valgrind不报告泄漏的原因。但是要小心,因为这意味着如果您想稍后保存该值,则必须复制函数返回的hostent,因为对gethost的进一步调用将覆盖它。

答案 1 :(得分:3)

没关系,因为返回的指针不指向堆栈或堆上的数据,而是指向某些静态变量。

http://linux.die.net/man/3/gethostbyname

  

函数gethostbyname()和gethostbyaddr()可能会返回指向静态数据的指针,这些指针可能会被以后的调用覆盖。复制struct hostent是不够的,因为它包含指针;需要深层复印。

答案 2 :(得分:2)

来自手册:

RETURN VALUE
       The gethostbyname() and gethostbyaddr() functions  return  the  hostent
       structure  or a NULL pointer if an error occurs.  On error, the h_errno
       variable holds an error number.  When non-NULL, the  return  value  may
       point at static data, ...

有些内存是在编译时保留的(即二进制内部代码)结构,该函数返回一个指向该内存的指针。

答案 3 :(得分:0)

在所有对它的引用都丢失之前,内存不会泄漏,在你的例子中,指针会被返回,所以仍然有对它的引用。

然而,对于大多数情况而言,依赖于代码的另一部分来释放动态内存是一个糟糕的设计决策。如果函数需要返回一个结构,例如,调用者应该这样做并传递指向结构的指针。