Cで:なぜスタックは、関数の構造が存在する外側を割り当てていますか?
-
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]);
(私はメモリから噴出しています、コード内の任意の軽微なエラーを無視する)
これは罰金を動作します。そして、Valgrindのは私が解放していないよという事実にもかかわらず、メモリを失ってる私に教えてくれません。
なぜ?私は、関数呼び出しが返すとスタックが消滅に割り当てられたものをと思いましたか?私はポインタを返すためか、それを何ですか?これは、どのような方法で危険なのですか?
解決
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, ...
いくつかのメモリを構成するためにコンパイル時(すなわち、バイナリ内のコード)で予約され、関数は、このメモリへのポインタを返す。
は、それに対するすべての参照が失われるまでまあメモリがリークされていない、あなたの例では、ポインタが返されます。
しかし、それは動的メモリを解放するために、コードの別の部分に依存するほとんどのケースで悪いデザインの決定です私見。機能は、例えば、構造体を返すために必要がある場合、呼び出し側はそれを行うと、構造体へのポインタを渡す必要があります。