2017-06-13 8 views
4

文字列を変更する小さな関数fooを書きました。セグメンテーションエラー初期化メソッドに依存するSIGSEGV

この機能を使用すると、SIGSEGVフォルトが発生することがあります。これは、文字列の初期化方法に依存します。呼び出し関数mainでは、文字列はメモリ割り当てとstrcpyを呼び出して初期化されます。私はその文字列を正しく変更することができます。

他の文字列(TestString2)は、変数を宣言すると初期化されます。私はこの文字列をトリミングすることはできませんが、SIGSEGVフォルトを取得します。

これはなぜですか?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 



void foo(char *Expr) 
{ 
    *Expr = 'a'; 
} 



int main() 
{ 
    char *TestString1; 
    char *TestString2 = "test "; 

    TestString1 = malloc (sizeof(char) * 100); 
    strcpy(TestString1, "test "); 

    foo(TestString1); 
    foo(TestString2); 

    return 0; 
} 
+0

Cには文字列型がありません。ポインタは配列ではありません! – Olaf

+0

@xing、Re "* TestString2は文字列リテラルを指します*"、いいえ、文字列を指します。文字列(https://en.wikipedia.org/wiki/Literal_(computer_programming))は、文字列を表すソースコードです。 – ikegami

答えて

6

TestString2の場合は、文字列定数のアドレスに設定します。これらの定数は変更できません。通常、メモリの読み取り専用セクションに存在します。このため、undefined behaviorを呼び出すと、この場合はクラッシュとして表示されます。

TestString1は、変更が許可されている動的に割り当てられたメモリを指しているため、有効です。

関連する問題