2013-06-14 19 views
7
int main() 
{ 
     char *x = "HelloWorld"; 
     char y[] = "HelloWorld"; 

     x[0] = 'Z'; 
     //y[0] = 'M'; 

     return 0; 
} 

上記のプログラムでは、HelloWorldは読み取り専用セクション(つまり文字列テーブル)になります。 xはその読み取り専用セクションを指しているので、その値を変更しようとすると未定義の動作になります。文字列内の文字列

しかし、yはスタックに割り当てられ、HelloWorldはそのメモリにコピーされます。 yを変更するとうまく動作します。以下のプログラムで

、内容が変更された場合の両方char *arrchar arr[]原因セグメンテーションフォールト:String literals: pointer vs. char array

は、ここに私の質問です。それは関数パラメータのコンテキストで異なる方法

void function(char arr[]) 
//void function(char *arr) 
{ 
    arr[0] = 'X'; 
}   
int main() 
{ 
    function("MyString");  
    return 0; 
} 
  1. 関数パラメータにはメモリが割り当てられませんか?

知識を共有してください。

+0

[パラメータの配列のサイズが渡される可能性があります](http:// stackoverflow。com/questions/1328223/sizeof-array-as-parameterとして) – delnan

+2

実際に配列パラメータのサイズの議論には関係ありません。これは、文字列リテラルと文字配列の恒常性に関するもので、大部分はサイズとは無関係です。 –

答えて

17

char arr[]は、char *arrと完全に等価であるため、定義のペアと宣言のペアは同等です。

void function(char arr[]) { ... } 
void function(char *arr) { ... } 

void function(char arr[]); 
void function(char *arr); 

問題は呼び出しコンテキストです。関数に文字列リテラルを指定しました。文字列リテラルは変更できません。あなたの関数は与えられた文字列リテラルを変更しようとしました。あなたのプログラムは未定義の動作を呼び出し、クラッシュしました。すべて完全にコーシャー。

文字列リテラルをstatic const char literal[] = "string literal";のように扱い、変更しないでください。

+0

'static const char'と言って、正しい保存期間を持つことさえできます。 – ouah

+0

True ...それに合わせて更新します... –

+1

C++標準では、実際には、文字列リテラルが 'const'であると指定しています。残念なことに、C標準はそうではないでしょう。これはおそらく、これらのリテラルを変更していないにもかかわらず、その宣言ではあまりにも多くのレガシーコードを破棄するためです。 – microtherion

6
function("MyString"); 

は、文字列リテラルの両方の場合であり、両方の場合において、文字列が変更不可能である

char *s = "MyString"; 
function(s); 

"MyString"と同様です。

function("MyString"); 

は、文字列リテラルのアドレスを引数としてfunctionに渡します。

+0

最初のケースでも、 'HelloWorld'は' char arr [] 'の場合のみ文字列リテラルです。右?? – Jeyaram

+1

最初のコード部分では、 'y'の文字列リテラルはスタックにコピーされる初期化子です。関数が複数回呼び出された場合、配列は各呼び出しで初期化されます。おそらく、他の場所からの定数初期化子を使用します。しかし、配列は変更可能です。 –

1

char * arr; 上記の文は、arrが文字ポインタであり、1文字または文字列を指すことができることを意味します。

& char arr []; 上記のステートメントは、arrは文字列であり、可能な限り多くの文字を格納することができますが、常に '\ 0'文字にカウントされるため、文字列になります。 (例:char arr [] = "a"

しかし、呼び出された関数のパラメータとして使用されるとき、渡される文字列は、仮引数に文字で格納され、違いはありません。

関連する問題