Pergunta

minha função:

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

em Main:

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

(ignore todos os erros menores no código, estou vomitando da memória)

Isso funciona bem. E Valgrind não me diz que estou perdendo memória, apesar do fato de não estar libertando.

Por quê? Eu pensei que as coisas alocadas na pilha desaparecem com a chamada de função retornando? Ou é porque eu devolvo o ponteiro? Isso é perigoso de alguma forma?

Foi útil?

Solução

host não é alocado na pilha, apenas um ponteiro para ela está na pilha. O ponteiro é copiado quando a função retorna, portanto não há nada de errado com o código.

Observe que gethostbyname Na verdade, não aloca dinamicamente a memória. Ele sempre retorna um ponteiro para o mesmo bloco de memória alocado estaticamente, e é por isso que Valgrind não relata um vazamento. Tenha cuidado, porém, porque isso significa que você precisa copiar o hostent devolvido por sua função, se você quiser salvar o valor para mais tarde, porque outras chamadas para gethost irá substituí -lo.

Outras dicas

Está bem e vaza porque o ponteiro retornado não aponta para dados na pilha ou na pilha, mas em alguma variável estática.

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

As funções gethostbyname () e gethostbyaddr () podem retornar Ponteiros para dados estáticos, que podem ser substituídos por chamadas posteriores. Copiar o hostente da estrutura não é suficiente, pois contém ponteiros; Uma cópia profunda é necessária.

Do manual:

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

Alguma memória é reservada no tempo de compilação (ou seja, dentro do binário do código) para a estrutura, a função retorna um ponteiro para essa memória.

Bem, a memória não vazou até que todas as referências a ela sejam perdidas, no seu exemplo, o ponteiro é retornado, para que ainda haja uma referência.

No entanto, o IMHO é uma decisão de design ruim na maioria dos casos para confiar em outra parte do código para liberar memória dinâmica. Se a função precisar retornar uma estrutura, por exemplo, o chamador deve fazê -lo e passar um ponteiro para a estrutura.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top