1

私はここにいくつかの行がありました:

#include <stdio.h>

char *tolower(char *data)
{
    char *p = data;
    while(*p)
    {
        printf("nilai p : %c\n",*p);
            if(*p >= 'A' && *p <= 'Z')
            {
                *p += ('a' - 'A');
            }
        p++;
    }
    return p;

}

int main()
{

    char *a = "HajAR BleH";
    char *b = tolower(a);

    printf("nilai b : %s\n",b);
    printf("nilai a - A : %d\n",'a' - 'A');
return 0;
}

次に、コンパイルされ、gdbで実行され、セグメンテーションがトレースされます

xxx@aaa:/tmp$ gcc -o aa aa.c --debug
xxx@aaa:/tmp$ gdb -q aa
Reading symbols from /tmp/aa...done.
(gdb) r
Starting program: /tmp/aa 
nilai p : H

Program received signal SIGSEGV, Segmentation fault.
0x0804841e in tolower (data=0x804855e "HajAR BleH") at aa.c:11
11                  *p += ('a' - 'A');
(gdb) 

質問

1.と同等で*p += ('a' - 'A');あると思います が、誤ってセグメンテーション違反が発生した場合、どうしてそうなる可能性がありますか?'H' += ('a' - 'A')72 += 32

2.charなぜ/byte下げるために('a'-'A')を追加する必要があるのですか?

今のところこれですべてです、事前に感謝します

4

5 に答える 5

7

文字列リテラルを変更しようとしています。変化する:

char *a = "HajAR BleH";

に:

char a[] = "HajAR BleH";

また、tolower() という標準ライブラリ関数が既にあり、実際にコードで使用する必要があります。独自の関数を別の名前で呼び出します。

于 2011-05-16T10:30:25.277 に答える
4

原因として最も可能性が高いのは、文字列リテラルで許可されてSEGVいるため、コンパイラが読み取り専用メモリに配置したことです。a

aの定義を次のように変更してみてください。

char a[] = "HajAR BleH";

スタイルの問題として、 と呼ばれる標準関数が既に存在します。これは、別の処理 ( 1 文字を小文字にtolower変換) を行います。これを念頭に置いて、次のことをお勧めします。

  1. 混乱を避けるために、関数に別の名前を付けます。
  2. 実装で使用tolowerして、1 つの文字を小文字に変換します。
于 2011-05-16T10:30:56.093 に答える
2

seg-fault の理由は、未定義の動作につながる読み取り専用メモリに存在する文字列リテラルを変更しようとしていることです。

変更してみる

char *a = "HajAR BleH";

char a[] = "HajAR BleH";
于 2011-05-16T10:30:35.940 に答える
0

1: 基本的にコードは正しいですが、定数文字列を変更しようとしています ( char *aredaにする必要がありますconst char *a)。変更できる別の文字配列を作成する必要があります。

2:('a' - 'A')小文字と大文字の ASCII 値の「差」を計算します (32)。

于 2011-05-16T10:36:23.857 に答える
0

読み取り専用メモリの問題と同様に、dataではなく返す必要がありますp。ループが終了pするまでに、ヌル ターミネータを指します。

于 2011-05-16T10:32:58.767 に答える