2013-04-15 7 views

答えて

16

上記のコードは問題を引き起こします。

最初のインスタンスは、静的な文字列の割り当てと定義として知られています。 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) 

また、データは最新のオペレーティングシステムでのアプリケーションのために分割されているかをよく読んでなければなりません。コードがどのように構築されているかを実際に理解することができます。

参照


  1. 2013年4月15日にアクセスされるデータセグメント<http://en.wikipedia.org/wiki/Data_segment>
  2. 2013年4月15日アクセスされるコードセグメント<http://en.wikipedia.org/wiki/Code_segment>
+2

ありがとう、ありがとう。 – VishalDevgire

+1

また、バリアントを追加します: 'char str [] =" Stack "' ... –

+0

@ValeriAtamanioukそして正しいでしょう。うまくいくでしょう。私に思い出させてくれてありがとう。 – DevNull

2

最初のケースでは、ポインタはconst char*を指し、プロセスメモリの読み取り専用部分に割り当てられます。
2番目のケースでは、メモリを動的に割り当てていて、イベントスタックは割り当てられたメモリに文字列 "Stack"をコピーします。

を使用して、メモリを最終的にメモリから解放する必要があります。

+0

私は読み取り専用領域(最初のケース)に書き込もうとするとどうなりますか? – VishalDevgire

+1

'const char *'は定数文字列ではありません。あなたのコンパイラはこれをやり遂げるのを防ぎます。 –

+1

あなたは大歓迎です。それは最初に理解することは容易ではありません... –

0

彼らが間違っているので、スタック内に格納することについて何かを主張する他の答えについては忘れてください。(うーん、今それらの答えは削除されています。)

case I:あなたがその内容"Stack"ある読み取り専用メモリ領域(.rodata節)を指すポインタstrを持っています。

case II:

あなたは、その内容変更であり、それを使用した後free(str)をinvockingによって解放されなければならない"Stack"、である(ヒープ内の)動的に割り当てられた領域を指すポインタstrを有します。

関連する問題