I. char *str = "Stack";
II. char *str = (char*) malloc(6);
strcpy(str, "Stack");
上記2つのアプローチの違いは何ですか?宣言された文字列と割り当てられた文字列の違い
カーテンの後ろで同じか何かが違っていますか?
I. char *str = "Stack";
II. char *str = (char*) malloc(6);
strcpy(str, "Stack");
上記2つのアプローチの違いは何ですか?宣言された文字列と割り当てられた文字列の違い
カーテンの後ろで同じか何かが違っていますか?
上記のコードは問題を引き起こします。
最初のインスタンスは、静的な文字列の割り当てと定義として知られています。 int
などの通常の変数、および文字列以外のデータ型の場合、そのような宣言はデータをスタックに割り当てます。文字列リテラル(つまり、"stack"
)で文字列を初期化する場合、メモリの読み取り専用部分に割り当てられます。
文字列自体は、メモリの読み取り専用部分に格納されるため、変更しないでください。ポインター自体を変更して、新しい場所を指すようにすることができます。
すなわち:
char strGlobal[10] = "Global";
int main(void) {
char* str = "Stack";
char* st2 = "NewStack";
str = str2; // OK
strcpy(str, str2); // Will crash
}
安全のために、あなたが実際すなわち、constのデータへのポインタとして割り当てる必要があります。
const char* str = "Stack"; // Same effect as char* str, but the compiler
// now provides additional warnings against doing something dangerous
第二は、上のメモリを割り当てる動的割り当て、として知られていますヒープ、スタックではありません。文字列は面倒なく修正できます。ある時点で、free()
コマンドを使用して、この動的に割り当てられたメモリを解放する必要があります。
スタックに静的な割り当てである文字列を割り当てる第3の方法があります。これにより、文字列を保持している配列の内容を変更することができ、静的に割り当てられます。要約すると
char str[] = "Stack";
:
Example: Allocation Type: Read/Write: Storage Location:
================================================================================
const char* str = "Stack"; Static Read-only Code segment
char* str = "Stack"; Static Read-only Code segment
char* str = malloc(...); Dynamic Read-write Heap
char str[] = "Stack"; Static Read-write Stack
char strGlobal[10] = "Global"; Static Read-write Data Segment (R/W)
また、データは最新のオペレーティングシステムでのアプリケーションのために分割されているかをよく読んでなければなりません。コードがどのように構築されているかを実際に理解することができます。
参照
<http://en.wikipedia.org/wiki/Data_segment>
<http://en.wikipedia.org/wiki/Code_segment>
最初のケースでは、ポインタはconst char*
を指し、プロセスメモリの読み取り専用部分に割り当てられます。
2番目のケースでは、メモリを動的に割り当てていて、イベントスタックは割り当てられたメモリに文字列 "Stack"をコピーします。
を使用して、メモリを最終的にメモリから解放する必要があります。
私は読み取り専用領域(最初のケース)に書き込もうとするとどうなりますか? – VishalDevgire
'const char *'は定数文字列ではありません。あなたのコンパイラはこれをやり遂げるのを防ぎます。 –
あなたは大歓迎です。それは最初に理解することは容易ではありません... –
彼らが間違っているので、スタック内に格納することについて何かを主張する他の答えについては忘れてください。(うーん、今それらの答えは削除されています。)
case I:
あなたがその内容"Stack"
ある読み取り専用メモリ領域(.rodata
節)を指すポインタstr
を持っています。
case II:
あなたは、その内容変更であり、それを使用した後free(str)
をinvockingによって解放されなければならない"Stack"
、である(ヒープ内の)動的に割り当てられた領域を指すポインタstr
を有します。
ありがとう、ありがとう。 – VishalDevgire
また、バリアントを追加します: 'char str [] =" Stack "' ... –
@ValeriAtamanioukそして正しいでしょう。うまくいくでしょう。私に思い出させてくれてありがとう。 – DevNull