7

そのため、C++ の文字列リテラルがどのように機能するかをよりよく理解したいと考えています。私は主に、文字列リテラルのアドレスをポインターに割り当てて渡している状況に関心があります。例えば:

char* advice = "Don't stick your hands in the toaster.";

ここで、プログラムの実行中にポインターをコピーして、この文字列を渡すだけだとしましょう。確かに、それはおそらく良い考えではありませんが、舞台裏で実際に何が起こっているのか興味があります.

別の例として、文字列リテラルを返す関数を作成するとします。

char* foo()
{
    // function does does stuff
    return "Yikes!"; // somebody's feeble attempt at an error message
}

ここで、この関数が非常に頻繁に呼び出され、文字列リテラルが呼び出される時間の約半分しか使用されないとします。

// situation #1: it's just randomly called without heed to the return value
foo(); 

// situation #2: the returned string is kept and used for who knows how long
char* retVal = foo();

最初の状況では、実際に何が起こっているのでしょうか? 文字列は作成されたばかりで使用されておらず、割り当ても解除されていませんか?

2 番目の状況では、ユーザーが文字列を必要とする限り、文字列は保持されますか? もう必要なくなったらどうなりますか...そのとき、そのメモリは解放されますか(そのスペースを指しているものが何もないと仮定します)?

誤解しないでください。このような文字列リテラルを使用するつもりはありません。文字列をチェックするためにコンテナーを使用する予定です (おそらく std::string)。これらの状況がメモリ管理やデータの破損に問題を引き起こす可能性があるかどうかを知りたいだけです。

4

2 に答える 2

23

文字列リテラルには型const char[N](Nは長さ + 1) があり、静的に割り当てられます。メモリの問題について心配する必要はありません。文字列がプログラムで使用されている場合は、すべて処理され、プログラム メモリのどこかに存在します (通常は読み取り専用)。

つまり、これらは「同じ」です。

static const char str[] = "a string";
"a string"

文字列リテラルを指すときは、配列の最初の文字を指しています。実際、タイプはconst char[]であるため、 経由でのみ安全にポイントできconst char*ます。文字列リテラルから への変換char*は推奨されておらず、安全ではありません。

// the "same"
static const char str[] = "a string";
const char* strPtr = str; // decays

const char* s1 = "a string";
char* s2 = "a string"; // allowed, implicit const_cast

*s1 = 'A'; // not allowed, it's const
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior)
于 2010-04-29T20:57:09.573 に答える
1

まず、foo の戻り値を const として宣言します。文字列リテラルは、恐ろしい「未定義の動作」を引き起こさずに変更できない定数であるためです。これにより、foo の戻り値を使用するポインターも const として宣言されるようになり、(通常は意図せずに) 行われる可能性のあるダメージが制限される可能性があります。文字列リテラルは、バイナリ実行可能ファイルの「テキスト」領域に格納されます。実行時にそのように作成されることはありません。

于 2010-04-29T20:59:48.970 に答える