2009-08-05 12 views
1

私はこのように、未定義の引数を持つ関数を呼び出すプログラムがあります。C /口が達者なメモリ管理{なしダングリング参照> whyy ??!}

#include <stdargs.h>
... /* code */ int main() {
GArray *garray = g_array_new (FALSE, FALSE, sizeof (char *)); /* the code above initialize the GArray, and say that the garray expect a pointer to char. */
function_name (garray, "arg2", "arg3" /* and so on ... */);
... /* code */ }

ノート「」との引数は文字列である、ということをので、関数内の_名前:だから

static void function_name (GArray *garray, ...) { 
    ... /* code */ 
    char *data;
data = va_arg (garray, gchar *); g_array_append_val (garray, data);
... /* code */ }

     、関数の戻り値は、teoricallyデータが指摘、無効にする電源を入れたときに、va_listの内の引数にデータポイントの場合、あまりにもガライインチ
(データポインターがメモリアドレスを指しているので、ダングリングリファレンスが発生します。

     しかし、そのようなことは起こっていないようだが、プログラムは正常に動作する。どうして? Cでは、関数に渡された引数はスタックに格納されるため、データのスタックは実際にはメモリになりますか?

thnkxたくさん。

答えて

5

Cプログラムで文字列定数を導入すると、静的な記憶期間を持つ名前の付いていない変更不可能なオブジェクトが作成されます。 「静的記憶期間」とは、プログラムの存続期間中存続することを意味します。

だから、あなたのコードでこれを持っている場合:

function_name (garray, "arg2", "arg3" /* and so on ... */); 

文字列「arg2に」と「ARG3は、」文字列定数です - 彼らは、プログラムメモリのどこかに存在し、プログラムの生活のため。多くの場合、これらはプログラムコード自体と同じ方法でテキストセグメントに格納されます。

function_name()に実際に渡されるもの(おそらくスタックにある)はポインタの文字列定数です。そして、それはあなたのGArrayがこれらの文字列定数へのポインタを格納することになります。

(配列初期化子として使用される文字列は、ではなく、文字列定数です)。

+0

あなたは静的な記憶期間を持つオブジェクトが作成されたと言っていますが、私はそれを知りません、thnxのカフェ、これは私の疑いを説明する! ; D – drigoSkalWalker

0

3つのいずれかに該当する:

次のいずれかの 1)g_array_append_valは、文字列のコピーを作っています。

または 2)スタックが再び上書きされるとすぐに、物事が壊れます。

void burn_stack(int size) 
{ 
    char data[8]={0,0,0,0,0,0,0,0}; 
    size-=8; 
    if (size>0) burn_stack(size); 
} 

burn_stack(256)を呼び出してみてください。 function_nameの後に、何かが引き続き機能するかどうかを確認してください。

または:3)実行可能ファイルの文字列セクションに格納され、ヒープやスタックではなく、const char "string"を使用しているため、無期限に存続します。

+0

正しくない - これらの文字列定数は静的な記憶期間を持つため、スタックに格納されない可能性があります。それらへのポインタはおそらくありますが、それはここで問題ではありません。 – caf

+1

もちろん、彼らは定数です。私の悪い。 –

関連する問題