16

この声明では:

char *a = "string1"

文字列リテラルとは正確には何ですか?それstring1ですか?このスレッドのため、CおよびC ++の文字列リテラルのタイプは何ですか?何か違うことを言う。

私の知る限り

int main()
{
    char *a = "string1"; //is a string- literals allocated memory in read-only section.
    char b[] = "string2"; //is a array char where memory will be allocated in stack.

    a[0] = 'X'; //Not allowed. It is an undefined Behaviour. For me, it Seg Faults. 
    b[0] = 'Y'; //Valid. 

    return 0;
} 

上記以外の点を追加してください。ありがとう。

デバッグ出力にエラーが表示されます a[0] = 'Y';

Reading symbols from /home/jay/Desktop/MI/chararr/a.out...done.
(gdb) b main
Breakpoint 1 at 0x40056c: file ddd.c, line 4.
(gdb) r
Starting program: /home/jay/Desktop/MI/chararr/a.out 

Breakpoint 1, main () at ddd.c:4
4   {
(gdb) n
6   char *a = "string1";
(gdb) n
7   char b[] = "string2";
(gdb) 
9   a[0] = 'Y';
(gdb) 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400595 in main () at ddd.c:9
4

1 に答える 1

26

文字列リテラルは、「二重引用符で囲まれた一連の文字」と見なすことができます。この文字列は読み取り専用として扱われる必要があり、このメモリを変更しようとすると、未定義の動作が発生します。必ずしも読み取り専用メモリに格納されているわけではchar[]なく、型はそうではありませんconst char[]が、未定義の動作です。タイプがない理由は、const後方互換性です。constCには最初は修飾子がありませんでした。C ++では、文字列リテラルのタイプはconst char[]。です。

では、なぜセグメンテーション違反が発生するのでしょうか。

  • char *ptr = "string literal"重要な点はptr、文字列リテラルが格納されている読み取り専用メモリを指すようにすることです。したがって、このメモリにアクセスしようとするとptr[0] = 'X'(ちなみに)と同等ですが*(ptr + 0) = 'X'、これはメモリアクセス違反です。

一方、char b[] = "string2";メモリを割り当てて文字列をコピー"string2"するため、変更は有効です。bこのメモリは、スコープ外になると解放されます。

文字配列のリテラル文字列初期化子を見てください

于 2012-10-09T08:33:39.867 に答える