в С:Почему структура, выделенная в стеке, существует вне функции?

StackOverflow https://stackoverflow.com/questions/2352260

  •  23-09-2019
  •  | 
  •  

Вопрос

моя функция:

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

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

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

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

из мануала:

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top