0

次のコードがあります。

#include <iostream>`

using namespace std;
int main() {
    char* data = new char;
    cin >> data;
    cout << data << endl;
    return 1;
}

char*文字列リテラルとして 26 の1 を入力すると、コンパイルされて出力されます。しかし、データとして27個実行すると、中止されます。理由を知りたいです。

なんで27なの?

それには特別な意味がありますか?

4

4 に答える 4

2

1 文字分のスペースしか割り当てていません。したがって、それ以上のデータを読み取ると、所有していないメモリが上書きされるため、未定義の動作になります。これは、結果に表示されているものです。

于 2012-06-21T22:56:43.707 に答える
0

C++ 実装の内部で特定の詳細を調べる必要があります。おそらく、mallocなどの実装です。コードは、C++ 標準によると UB であるバッファーの末尾を超えて書き込みます。なぜこのように動作するのかを理解するには、上書きした 27 または 28 バイトに何を格納する必要があるかを知る必要があります。

最も可能性が高いのは、メモリ アロケータが割り当てられたブロックと解放されたブロックを追跡するために使用するデータ構造に損傷を与え始めた時点で、たまたま 27 個のブロックが発生したことです。しかし、UB を使用すると、動作が最初に表示されたほど一貫していないことに気付く場合があります。C++ プログラマーとして、そのような詳細について知る「資格」は実際にはありません。なぜなら、それらについて知っていれば、それらに依存し始め、予告なしに変更される可能性があるからです。

于 2012-06-22T01:33:15.300 に答える
0

動的に 1 バイトのストレージを割り当てます。複数を割り当てるには、次のようにします。

char* data = new char[how_many_bytes];

文字列リテラルを使用すると、それだけのスタック スペースが自動的に割り当てられます。動的に割り当てる場合、正しいバイト数を取得する必要があります。そうしないと、segfault が発生します。

于 2012-06-21T22:58:04.800 に答える
0

これは単にUndefined Behavior、別名「UB」です。プログラムは何でもできるか、何もしないことができます。表示される効果は再現できません。

なんでUBなの?

単一の値にスペースを割り当て、それをゼロで終わる文字列charとして扱うためです。ゼロは 1 つの値を占めるため、実際のデータ用の (保証された) スペースはありません。ただし、C++ の実装では通常、非効率的なチェックが追加されることはないため、所有していないメモリの一部にデータを格納することは避けられます。UB により、クラッシュするか、無効な結果が生成されるか、その他の悪影響が生じるまでは。char

これを正しく行うには、std::string代わりに, を使用し、 orを使用char*しないでください(aが自動的に行います)。newdeletestd::string

次に、 を使用std::getlineして、入力の 1 行を文字列に読み込みます。

于 2012-06-21T22:59:38.517 に答える