2011-12-30 8 views
0

次の2つのコードスニペットは、エラー/警告なしでコンパイルされますが、実行中にクラッシュします。親切に私を教えてください。プログラム2については文字列へのポインタ

プログラム1

int main() 
{ 
    char *p= "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

プログラム2

int main() 
{ 
    char *p= "Hello" ; 
    Char *q="mug" 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

私は出力が 'ハグ' であると予想。

答えて

8

char *p= "Hello"; 

あなたはリテラル文字列を定義しています。文字列リテラルは定数データであり、あなたが知っているように、それらを変更すると未定義の動作(多くの場合クラッシュ)が発生します。

const char *p = "Hello"; 

これを修正しようとすると、コンパイラはエラーをスローします。

は今、あなたはその代わりに、それを定義した場合:

char p[] = "Hello"; 

メモリは、スタック上に割り当てられている、あなたはそれを変更することができます。

int main(int argc, char *argv[]) 
{ 
    char p[] = "Hello" ; 

    *p = 'B' ; 
    printf("\n%s",p); 

    return 0; 
} 

出力するプログラム2についてはBello

は、スタック上にあるだけqニーズに注意してください。 pは文字列リテラルへのポインターのままにしておくことができます。

int main() 
{ 
    const char *p = "Hello" ; 
    char q[] = "mug"; 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 

出力Hug

+0

ジョーのおかげです。 – intex0075

+0

@ intex0075助けてくれてうれしいです。 – JoeFish

0

両方のサンプルで、未定義の動作をもたらす文字列リテラルを変更しています。あなたが書くべきこと

0

は次のとおりです。

char p[] = "Hello"; 

(char型のP [] =「こんにちは」)上記のフォームは、私が来て、値の配列を持っている」、コンパイラに伝え、できるだけ多くを割り当ててください。彼らのために必要とされるスペース。

int i [] = { 1, 2, 5, 100, 50000 }; 

iは5の値の配列へのポインタになります。

+0

ええ、私はそれを掲載して削除した直後にそれを実現しました。混乱させて申し訳ありません。 – user1118321

0

char * p = "test"の形式で静的文字列を作成すると、ポインタの内容を変更することはできません。あなたのケースでは、ポインタの内容を変更しようとすると、あなたが観察しているエラーになります。

0

プログラム2を文字列リテラルを使用しないように変更しました。期待通りに "ハグ"を表示します。

あなたが
#include <string.h> 
#include <stdio.h> 

int main() 
{ 
    char p[10]; 
    char q[10]; 
    strcpy(p,"Hello"); 
    strcpy(q,"mug"); 
    *q = *p ; 
    printf("\n%s",q); 

    return 0; 
} 
+0

これは答えですか? –

+0

コードが失敗する理由は4つあります。この回答は正しい方法を説明しています。 –

0

文字列「こんにちは」と「マグカップ」は、読み出し専用メモリに保存され、あなたがそこに書き込もうとしています。

$ gcc -S a.c 
$ cat a.s 
    .file "a.c" 
    .section  .rodata 
.LC0: 
    .string "Hello" 
.LC1: 

セクションは "rodata"(読み取り専用データ)であることに注意してください。

+0

Atomは、リテラルが "コード/テキストセグメント"に格納されていることを意味します。それがROになるのはなぜですか? – intex0075

+0

リテラルは、データ(コードではない)を含むセクション ".rodata"に格納され、ELF実行可能ファイルのフラグはセクションが読取り専用であることを示します。 ".text"や ".data"などのセクションもあります。 "readelf --sections executable_file"を使用してすべてのセクションを印刷することができます。 "Flg"カラムはセクションのアクセス権を指定します。 –

関連する問題