1

それで、私はCについて学び続けます。そして、私はいくつかの興味深い質問があります。ヒープに物を置くのを間違えなければ、使用する必要がありますmalloc。しかし、どうchar * strでしょうか。どのメモリセグメントにstr配置されますか?.bssセグメントに配置されることを読みました(そのため、Cでは文字列を変更できません)。これは正しいです?それともスタックに入れられますか?

はいの場合、プログラムの終了時にこのメモリを解放する必要がないのはなぜですか?また、各関数のどのメモリセグメントコードにありますか?言い換えれば、関数へのポインタが指すセグメントは何ですか?助けてくれてありがとう!Cでのメモリ管理をよりよく理解しようとしています。

4

6 に答える 6

4

配列のメモリが割り当てられないと言った場合char * str、ポインタ自体のメモリのみが割り当てられます。おそらくヒープ上で文字列用のメモリを手動で割り当て、おそらく手動で解放する必要があります。

「C では文字列を変更することはできません」は誤りです。.rodata文字列定数を変更することはできず、文字列定数は(読み取り専用セクション) のような場所に割り当てられます。関数コードは、他のコードと同様に、.text.

于 2013-03-22T17:30:53.267 に答える
4

関数内に定義を入れるとchar *str;、それは「ポインタへの」型の自動変数になりますchar

これはスタック上にあり、関数が戻るとスタックのその部分は使用されなくなります (必要に応じてスタック ポインターを移動するコードを発行することにより、コンパイラーがこれを処理します)。理論的には、スタックの存在は純粋に実装の詳細です。実際には、C には常にコール スタックがあり、ほとんどすべての実装が多かれ少なかれ同じ方法でそれを管理しますが、実際に管理されるとはいえ、自動変数が格納されるメモリは「スタック」と呼ばれる可能性があります。

定義を関数の外に置くとchar *str;、それは静的ストレージ期間を持つグローバル変数になります。

これは読み書き可能なデータ セグメントに格納され、プログラムが終了すると使用されなくなります (おそらく OS がこれを処理しますが、原則的にはコンパイラによって発行されたコードである可能性があります)。それはゼロで初期化されているため (そしてヌル ポインターがすべてのビット ゼロで表されるアーキテクチャを想定している) はい、それは bss セグメントに入ることができます。これは、特に静的ストレージ期間を持つゼロで初期化された読み書きオブジェクト用です。繰り返しになりますが、静的な期間のオブジェクトを格納する方法の詳細は実装次第ですが、これが一般的な方法です。

文字列を定義していないため(文字列リテラルを使用したことは言うまでもありません)、これは文字列リテラルが変更できないこととは何の関係もありません。文字列を指す可能性がありますが、(まだ) 指していないポインターを定義しました。

于 2013-03-22T17:31:26.730 に答える
2

C では、すべてのローカル変数がスタックに置かれます。変数strは文字ポインタです。メモリアドレスが含まれています。スタック上には、 と呼ばれるこのポインターのみが存在しますstr

char * str;

これにより、ポインタのサイズ (32/64 ビットでは 4 または 8 バイト) のメモリがstack に割り当てられます。

str = malloc(1024);

mallocヒープに 1024 バイトを割り当て、そのメモリ領域の最初のバイトへのポインタを返します。このポインターはstr、スタック上の に保存されます。

str関数(strローカル変数である)が戻ると、変数は解放されます。

指しているメモリ領域strは自動的に解放されません。で手動で行う必要がありますfree(str)

弦交換可能!ただし、定数リテラルではありません。

char string[4] = "foo";
string[0] = 'F'; //will work

char * stringconst = "foo";
stringconst[0] = 'F'; // this will segfault

「foo」は(うまくいけば)読み取り専用メモリ領域に配置されるため、上記は機能しません。

于 2013-03-22T17:37:39.700 に答える
1

同様の質問への回答を読んでいるときに見つけた2つのリンク。これらは、問題をもう少しよく理解するのに役立つかもしれません。

C プログラムのメモリ レイアウトと C文字列のストレージ

于 2013-03-22T18:04:13.930 に答える