в C: Почему делает выделенную структуру стека, существуют за пределами функции?

моя функция:

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]);

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

это хорошо работает. и Valgrind не говорит мне, что я теряю память, несмотря на факт, который я не освобождаю.

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

5
задан Joachim Sauer 28 February 2010 в 19:21
поделиться

4 ответа

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

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

10
ответ дан 18 December 2019 в 11:55
поделиться

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

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

0
ответ дан 18 December 2019 в 11:55
поделиться

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

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

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

3
ответ дан 18 December 2019 в 11:55
поделиться

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

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

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

2
ответ дан 18 December 2019 в 11:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: