2

何かをしようとしていたときにこれを取得します(理解するためだけに)。この動作を説明してください:


最初の試み:

void main()    
{  
    char src[] = "vinay";
    int i;
    // char name[5] = "test";
    char *name=  "abcde";
    printf("%s \n", name);
    if (*(name+5) == '\0')
        printf("6th char is null\n");
    strcpy(name,src);
    printf("printcheck \n");
    for (i=0 ; i <6 ; i++)  
    {
        printf("%c \n", *(name+i));
    }
    printf("%s \n",name);    
}

出力:

abcde 
6th char is null
zsh: 16644 segmentation fault (core dumped)  a.out

2 回目の試行:

void main()
{
    char src[] = "vinay";
    int i;
    char name[] = "pqrst";
    //char *name=  "abcde";
    printf("%s \n", name);

    if (*(name+5) == '\0')    
        printf("6th char is null\n");

    strcpy(name,src);
    printf("printcheck \n");

    for (i=0 ; i <6 ; i++)
    {
        printf("%c \n", *(name+i));
    }

    printf("%s \n",name);
}

出力:

pqrst 
6th char is null
printcheck     
v     
i   
n   
a     
y 
vinay

================================================== =========================================

質問: 試行 1 でクラッシュするのはなぜですか? 私はSolarisマシンでこれを試していましたカーネルバージョン:SunOS 5.8 Generic 117350-43 Oct 2006

4

8 に答える 8

8

この種の操作のため:

char name[] = "pqrst";

定数文字列をスタック上の配列にコピーします。ローカル コピーを自由に変更できます。

ただし、この種の操作:

char *name=  "abcde";

文字列のアドレスをポインタに割り当てるだけです。その文字列を変更しようとすると、定数文字列を変更しようとしています。この文字列は保護された領域にあるため、許可されていません。

于 2009-10-21T15:26:03.767 に答える
5
char* name = "abcde";

書き込みアクセス権がない定数メモリ空間へのポインタを割り当てます。

char name[] = "vinay"; 

書き込み可能な配列を割り当てます。

于 2009-10-21T15:24:39.333 に答える
5

文字列リテラルは変更できません ( Undefined Behaviorのペナルティの下で)。それらへのポインタを宣言するときは、本当にそれを作成する必要がありますconst

const char *name = "string literal";

標準からの引用:

6.4.5 String literals

6 .... If the program attempts to modify such an array,
  the behavior is undefined.
于 2009-10-21T15:26:23.340 に答える
1

問題は次の行にあります。

char* name = "abcde";

文字列"abcde"静的な const文字列であり、書き込みが許可されていない実行可能ファイルの一部に埋め込まれています。次に を実行するとstrcpy(name, src)strcpyはメモリの静的部分に書き込もうとするため、アクセス違反が発生します。

一方、これを書くと:

char[] name = "abcde";

thennameは、ローカル関数のスタック内に割り当てられた配列です。いつでもスタックに書き込むことができるので、これは問題なく機能します。

于 2009-10-21T15:26:19.347 に答える
0

必ずしも変数名にスペースを割り当てていないことが原因であるとは限りません。スタック上のランダムな領域の上に vinay をダンプしていますが、これは他の何かのために予約されている可能性があります。malloc を使用して文字列にスペースを割り当てます。問題ありません:)

于 2009-10-21T15:26:39.430 に答える
0

文字列定数 (「abcde」) はおそらく読み取り専用のデータ セグメントにあるため、

char src[] = "vinay";
char *name = "abcde";
[...]
strcpy(name, src); /* copy string src to whatever name points to */

読み取り専用のメモリ ロケーションにコピーすると、segfault が発生します。

2 番目のプログラムは機能します。これで、ターゲット メモリ領域がすべてのローカル変数がある場所に配置され、そのメモリ領域 (スタック) が書き込み可能になります。

char src[] = "vinay";
char name[] = "abcde";
[...]
strcpy(name, src); /* copy string src to the memory area designated by name */
于 2009-10-21T15:26:52.830 に答える
0

コンパイラによって初期化されたメモリを変更しているため、試行 1 は失敗します。のように引用符を使用して、char *name = "something"(のようにスタック上ではなく) 一定のメモリ空間で文字列を定義しchar name[] = "vinay" ます代わりにa を使用して変更可能にし、char *代わりに自分でメモリを割り当てます。

char *name = NULL; 
name = (char *) malloc(6);

後で忘れないfree()でください!

于 2009-10-21T15:28:05.990 に答える
0

最初の試行では、 name は const メモリ リソースへのポインタです。2回目の試行では、それを変更し、テキストをそのメモリ領域に配置する前に割り当てが行われます。

動的割り当ては次の方法で行われます。

char * buffer = malloc(STRING_SIZE);

また

char buffer[STRING_SIZE];
于 2009-10-21T15:25:52.157 に答える