в C: Почему выделенная структура стека существует вне функции? - PullRequest
5 голосов
/ 28 февраля 2010

моя функция:

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;
    }
}

в основном:

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

(игнорировать любые незначительные ошибки в коде, которые я извергаю из памяти)

это отлично работает. и Вальгринд не говорит мне, что я теряю память, несмотря на то, что я не освобождаю.

Почему? Я думал, что вещи, размещенные в стеке, исчезают при возврате вызова функции? или это потому что я возвращаю указатель? это опасно в любом случае?

Ответы [ 4 ]

10 голосов
/ 28 февраля 2010

host не выделяется в стеке, только указатель на него находится в стеке. Указатель копируется, когда функция возвращается, поэтому в коде нет ничего плохого.

Обратите внимание, что gethostbyname на самом деле динамически не выделяет память. Он всегда возвращает указатель на один и тот же статически выделенный блок памяти, поэтому valgrind не сообщает об утечке. Однако будьте осторожны, потому что это означает, что вы должны скопировать hostent, возвращенный вашей функцией, если вы хотите сохранить значение для более позднего времени, потому что дальнейшие вызовы gethost перезапишут его.

3 голосов
/ 28 февраля 2010

Это нормально и делает утечку, потому что возвращаемый указатель указывает не на данные в стеке или куче, а на некоторую статическую переменную.

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

Функции gethostbyname () и gethostbyaddr () могут возвращать указатели на статические данные, которые могут быть перезаписаны последующими вызовами . Копирование структуры hostent недостаточно, поскольку оно содержит указатели; требуется глубокая копия.

2 голосов
/ 28 февраля 2010

из руководства:

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, ...

Некоторая память зарезервирована во время компиляции (т.е. внутри двоичного кода) для структуры, функция возвращает указатель на эту память.

0 голосов
/ 28 февраля 2010

Ну, память не просочилась до тех пор, пока не будут потеряны все ссылки на нее, в вашем примере указатель возвращается, так что на него все еще есть ссылка.

Однако в большинстве случаев это плохое проектное решение, полагаться на другую часть кода для освобождения динамической памяти. Если функции необходимо вернуть структуру, например, вызывающая сторона должна сделать это и передать указатель на структуру.

...