2009-04-05 21 views
8

C++では文字列リテラルに関する疑問がほとんどありません。文字列リテラル

char *strPtr ="Hello" ; 
char strArray[] ="Hello"; 

ここで、strPtrとstrArrayは文字列リテラルと見なされます。

文字列リテラルは読み込み専用メモリに保存されているため、値を変更することはできません。

私たちはどちらも上記の文は違法でなければなりません

strPtr[2] ='a'; 
and strArray[2]='a'; 

を行うことはできません。 コンパイラはどちらの場合もエラーをスローする必要があります。

コンパイラは文字列リテラルを読み取り専用メモリに保持します。したがって、コンパイラは文字列リテラルを変更しようとするとエラーをスローします。

また、constデータも読み取り専用とみなされます。

文字列リテラルとconstデータの両方が同じように扱われますか? 文字列リテラルからconst_castを使用して定数を削除すると、値を変更できますか?

文字列リテラルは正確にどこに格納されますか? (プログラムのデータセクション)

答えて

16

strPtrとstrArrayは文字列リテラルと見なされます。

いいえ、そうではありません。文字列リテラルは、コード内に表示されるものです。たとえば、"Hello"です。 strPtrポインタ(これは現在実行可能ファイルでコンパイルされています)です。それはconst char *であるはずです。 C標準に従ってconstを合法的に削除することはできず、使用時には定義された動作が期待されます。 strArrayは、リテラルのコピーを含む配列です(実行可能ファイルでコンパイルされます)。

上記の両方の文は違法です。コンパイラはどちらの場合もエラーをスローする必要があります。

いいえ、そうしてはいけません。 2つのステートメントは完全に合法です。状況により、最初のものは定義されていません。しかし、彼らがconst charへのポインタであった場合はエラーになります。

私が知る限り、文字列リテラルは他のリテラルと定数と同じ方法で定義することができます。ただし、次のような違いがあります。

// These copy from ROM to RAM at run-time: 
char myString[] = "hello"; 
const int myInt = 42; 
float myFloats[] = { 3.1, 4.1, 5.9 }; 

// These copy a pointer to some data in ROM at run-time: 
const char *myString2 = "hello"; 
const float *myFloats2 = { 3.1, 4.1, 5.9 }; 

char *myString3 = "hello"; // Legal, but... 
myString3[0] = 'j';   // Undefined behavior! (Most likely segfaults.) 

ここにはROMとRAMの使用が一般的です。プラットフォームがRAM(例えば、ほとんどのNintendo DSプログラム)のみである場合、constデータとなることがあります。ただし、書き込みは未定義です。 constデータの場所は、通常のC++プログラマにとって重要ではありません。

8
char *strPtr ="Hello" ; 

strPtr"Hello"リテラル文字列を指すcharへのポインタを定義 - このポインタの有効なタイプはconst char *あります。 pointeeにstrPtrによって変更が許可されていません(そうしようとするとUBが呼び出されます)。これは古いCコードの下位互換性の機能です。この規約はC++ 0xでは推奨されていません。

変更:文字列リテラルの種類が「のconst char型の配列」[...]

「charの配列」から変更されたのconst 作られた文字列リテラル附属書Cを参照してください。 理由:これは、不適切なオーバーロードされた関数を呼び出すのを避けます。

元の機能への影響:明確な機能のセマンティクスに変更してください。変換の難しさ:文字列リテラルをchar *に変換できるため、シンプルな構文変換が可能です。 (4.2)。最も一般的な例は、新しいが、廃止標準変換によって処理されます。潜在的に変更可能なメモリへのポインタとして文字列リテラルを治療するために正当な理由があるプログラム:広く使われている方法

char* p = "abc"; // valid in C, deprecated in C++

char* q = expr ? "abc" : "de"; // valid in C, invalid in C++

おそらくまれです。

char strArray[] ="Hello"; 

strPtrの宣言された型である - それはヌルターミネータ即ち6つの文字を含む文字列Helloを含む不特定サイズの文字の配列です。ただし、初期化によって完全な型になり、型は6文字の配列になります。 strPtrによる変更は問題ありません。

文字列リテラルは正確にどこに格納されますか?

実装が定義されています。古いCおよびC++コンパイラは、あなたが欲しいものを書くことができ++純粋なデータ保護の高い基準が利用できなかった低レベルのコーディングに基づいていた、と彼らも強制することはできません、一般的にCおよびCで

+0

"strPtrの宣言された型は"です、strArrayを意味しますか? – 4pie0

1

..

アドレスを使って遊ぶ方法がわかっている場合は、constポインタにアクセスして変更するコードも記述できます。

C++はコンパイルレベルの保護をいくつか実行しますが、実行時には保護はありません。独自のスタックにアクセスし、その値を使用してconstポインタに入っているデータを操作することもできます。

これは、アクセスするものが参照であり、データ保護のすべてのルールを管理する固定構造であり、アクセスも変更もできない隠しポインタを持っているため、C#が発明された理由です。

主な違いは、C++はコンパイル時の保護しか提供できませんが、C#は実行時でも保護されます。

関連する問題