0

重複の可能性:
文字列への書き込み時にセグメンテーション違反が発生するのはなぜですか?

私はC/C ++を初めて使用し、それを学習しようとしています。次の関数を作成しましたが、大文字の値を* stringに割り当てようとすると、例外がスローされます。CPP1.exeの0x00411820で未処理の例外:0xC0000005:アクセス違反の書き込み場所0x00417754。

void ToUpper(char* string)
{
    while(*string != '\0')
    {
        if(*string >= 97 && *string <= 122)
        {
            int symbol = *string;
            *string = symbol - 32;
        }
        string++;
    }
}

使用法:

char* x = "text"; 
ToUpper(x); 

手伝っていただけませんか?

4

7 に答える 7

3

変化する

char* x = "text"; 

char x[] = "text"; 

終わり

于 2012-11-07T09:02:10.667 に答える
2

const 文字列を変更しようとしないでください。この種の操作には常に文字配列を使用してください。

于 2012-11-07T09:00:19.243 に答える
1

「テキスト」のメモリは.readonlyセクションに割り当てられます。

char* x = "text"; 

読み取り専用セクションを変更しようとすると、未定義の動作になります。

gcc -S filename.cアセンブリ コードを表示するために使用します。これにより、「テキスト」の所在についてより多くのアイデアが得られます。

他の人が示唆したように、char x[] = "text"代わりに使用することをお勧めします。

于 2012-11-07T09:07:19.990 に答える
1

文字列リテラルをポインターで変更しようとするとエラーになります。

void f()
{
   char * p = "Naee";
   p[2] = 'm'; // error: assignment to const; result is undefined
}

文字列リテラルを定数にすることで、ストレージの割り当てとアクセスを大幅に最適化できます。変更できる文字列が必要な場合は、文字を配列にコピーする必要があります。

void f()
{
   char p [] = "Eero"; 
   p [0] = 'Z'; // ok
}
于 2012-11-07T09:22:17.593 に答える
1
main()
{
    char *a = "text";
    char *x = malloc(strlen(a)+1); 
    strcpy(x,a);
    ToUpper(x);
    // ToUpper(a); // Fails
    printf("%s %s\n",a,x);
}

出力:text TEXT

ToUpper(a) は失敗します。これは、保護されたメモリ領域で文字列が置き換えられるためです (少なくとも 64 ビットの x86 プロセッサには [rip] 相対アドレス指定モードがあるため、コードの途中で置換される可能性が最も高いため、配置すると有利になります)。コード行間のデータ...

char x[]="text";x の完全な配列がスタックに配置されるようになったため、これも機能します。ポインターのみがスタックに置かれる場合char *x = "text";、コンテンツは制限された (読み取り専用) メモリを指します。

于 2012-11-07T09:08:29.007 に答える
0

このように使用でき、変数を作成する必要はありませsymbol

*string=*string-32;

ただし、渡すarrayのではなく、呼び出し環境で関数に渡しますstring literal

それで

char * str[] ="hello";
ToUpper(str);
于 2012-11-07T09:05:01.230 に答える
-1

代入ステートメントで値を型キャストする必要があります。

*string = *(char *)symbol - 32;

于 2012-11-07T09:01:09.233 に答える