4

次のように:

#include <set>

std::set<const char *> global = std::set<const char *>();
void x() {
    const char *c = "a";
    const char *d = "b";

    global.insert(c);
    global.insert(d);
}

int main() {
    x();
    for (std::set<const char *>::const_iterator iter=global.begin(), end=global.end(); iter!=end; ++iter) {
        printf("%s\n", *iter);
    }

    return 0;
}

結局、さすがに受け取りab印刷しました。

それでも、たとえば、そのセットがbozoオブジェクトの一部であった場合、そのセットとして、の存続期間が終了するまで続くという保証はありますbozoか?それともstrdup、確かに文字列を使用する必要がありますか?

4

1 に答える 1

8

文字列リテラルには静的な保存期間があるため、まったく問題ありません。つまり、プログラムの期間中、文字列はメモリ内に存在します。ただし、とを次のように配列として宣言cした場合は問題ありません。d

const char c[] = "a";
const char d[] = "b";

これは、配列が文字列リテラルで初期化されると、リテラルの文字が配列にコピーされるためです。その配列には自動保存期間があるため、関数の最後に内容が破棄されますx。それでも実行した場合は、配列global.insert(c)の最初の要素へのポインターをプッシュしますが、cその配列はそれほど長くは存在しません。

ここにいくつかの標準的な引用があります。まず、§2.14.5/ 8:

通常の文字列リテラルおよびUTF-8文字列リテラルは、ナロー文字列リテラルとも呼ばれます。狭い文字列リテラルのタイプは「arrayofn です。ここで、n は以下に定義する文字列のサイズであり、静的ストレージ期間(3.7)があります。const char

そして今、静的ストレージ期間の定義(§3.7.1/ 1):

動的ストレージ期間がなく、スレッドストレージ期間がなく、ローカルでないすべての変数には、静的ストレージ期間があります。これらのエンティティのストレージは、プログラムの期間中(3.6.2、3.6.3)持続するものとします。

于 2012-12-25T23:59:54.403 に答える