0

久しぶりにC++をやっていて、気になることがいくつかあります。ここで同様の質問を見つけましたが、どれも私の問題を解決しません。それで、取引は何ですか?

私は持っています

SomeClass*** world;

これは、SomeClassオブジェクトへのポインターのマトリックスを示します。

後で、コンストラクターで、初期化しようとすると、次のようにします

for(int i = 0; i<20;i++)
    for(int j = 0;j<20;j++)
        world[i][j] = new SomeClass();

そしてそれはメッセージで壊れます:場所0xcdcdcdcdを読んでいる違反にアクセスしてください。このメッセージの意味を読みましたが、それでも、どのように機能させるのかわかりません。

前もって感謝します!

4

3 に答える 3

4

変数を宣言すると何が得られるかを理解することは非常に重要だと思います。のように、実際にメモリに作成されるもの。

では、を見てみましょうSomeClass*** world;。これはあなたに何をもたらしますか?それはあなたにポインタのマトリックスを手に入れますSomeClassか?いいえ、そうではありません。実際、これによって1つのものと1つのものだけ(単一のポインター)が得られることを知って驚かれるかもしれません。はい、そうです、たった1つのポインタです。ポインタであるこのworld変数を定義しました。それから得られるのはそれだけです。その単一のポインタ。

次に、このポインタを使用して、へのポインタを指す他のポインタを指す必要がありますSomeClass。しかし、それが指し示すものはまだ存在していません。したがって、 20まで繰り返しiて実行すると、まだ存在していないポインタのマトリックスにアクセスしようとしています。jworld[i][j]

を使用しながら、作成したものを機能させるにSomeClass***は、ポインタのマトリックスを割り当てる必要があります。

world = new SomeClass**[20];
for (int i = 0; i < 20; i++) {
  world[i] = new SomeClass*[20];
}

したがって、最初に20の配列を割り当てSomeClass**、次にそれらの各ポインターが割り当てられた20の配列を指すようにしSomeClass*ます。これはあなたが望むものをあなたに与えます...

しかし、待ってください-これは醜いです。これは、C++の記述方法ではありません。理由もなく、非常に多くの動的割り当て。それはまた、あなたがそれを終えたときにあなたがすべてを覚えていなければならないことを意味しますdelete-そしてそれも醜いです。動的割り当てに依存しない場合、これはすべてはるかに簡単になります。ポインタを使用する代わりに多次元配列を作成するだけで、すでに作業がはるかに簡単になります。

SomeClass* world[20][20];

これworldで、へのポインタの20x20配列になりますSomeClass。あなたは実際それをメモリに入れます。以前のようにポインタを取得するだけではありません。ポインタの多次元配列全体を取得できます。あなたはラッキーです。

これで、ポインタをまったく使用しないことで、さらに改善することができます。現時点では、オブジェクトを動的に割り当てSomeClass、配列内のオブジェクトにポインタを固定する必要があります。SomeClassしかし、代わりにの配列を持ってみませんか?

SomeClass world[20][20];

SomeClassこれで、オブジェクトの多次元配列ができました。人生はこれよりずっと良くなることはありません。手動で何かを割り当てたり削除したりする必要はありません。各要素がすでにSomeClassオブジェクトであり、サービスの準備ができているメモリ内の多次元配列全体が提供されます。

標準ライブラリのコンテナを使用することで、さらに安全性を向上させることができます。C ++ 03を使用している場合は、を使用できますがstd::vector<std::vector<SomeObject> >、これは少しやり過ぎかもしれません。ただし、C ++ 11では、従来の配列を使用してきちんと置き換えられ、全体的に安全になるタイプが導入されていますstd::array。あなたはそれをこのように使うことができます:

std::array<std::array<SomeObject, 20>, 20> world;
于 2012-12-22T11:42:41.783 に答える
3

実際に発生するエラーは、初期化されていないポインタを使用した場合です。0xcdcdcdcdは、VisualStudioのメモリの「塗りつぶしパターン」です。これは、使用時に「通知」されるように選択されています。これにより、メモリアクセス違反が発生します。

それを解決する方法:「c++で2つの次元配列を割り当てる方法」のためのグーグル。

于 2012-12-22T11:07:55.843 に答える
3

20x20の配列をメンバーとして(またはスタック上に)割り当ててから、次のように入力します。

SomeClass *world[20][20];
for ...

サイズが一定でない場合は、行ごとに割り当てる必要があります。

于 2012-12-22T11:12:58.377 に答える