1

私はグローバル配列を使用しています(私はそれらが悪であることを知っています)。これはそれほど問題ではありませんが、同じであるはずなので、なぜ一方の方法で機能し、もう一方の方法では機能しないのかわかりません。(それ以外の場合は、現在機能している方法でメモリの割り当てを解除する必要があります)。

とにかく、私はこのヘビのクラスを持っています。私が作りたいのは、これがグローバル配列です。

Snake snakes[8];

私はこれと相互作用するいくつかの(またはとにかく)いくつかのクラスと関数を持っています。問題の問題は、Snakeクラスのsetter関数で発生します。正常にコンパイルされますが、segfaultsです。結局、これはnullポインタ(0x0)でした。理由はわかりません。この場合のスタックトレースは、スネークヘッダーを含み、次のような別のファイルからの関数呼び出しから取得されました。

extern Snake * snakes;

配列の名前はポインタなので、これでうまくいくはずだと思いました。奇妙なことに、そうではありません。理由はわかりません。

しかし、宣言を以前の状態から変更すると、次のようになります。

Snake * snakes;

そして後でそのように割り当てます:

snakes = new Snake [8];

できます!しかし、ヘビの数が一定の場合は、他の必要のないものの割り当てを解除する必要があります。(8)。

また、問題の関数呼び出しは、毎回8つの要素があった0番目の要素にアクセスします。

これを引き起こす原因は何ですか?

ちなみに、名前空間にある場合、グローバル変数は依然として悪ですか?(匿名ではありません)。私はOOの習慣を身につけ、物事を論理的に構造化しようとしているので、これは私の最後の努力、カプセル化、組織化などと比較してすべてが理にかなっていると確信しています。(そしておそらく数年以内に、コンパイル時)。それでも、設定のための関数呼び出しにスコープ変数を含める必要があるようです...悪いようです。それは適切ですか、それとももっと良い方法がありますか?(その後、グローバル、名前空間、またはその他)

編集:エラーは、メンバー関数の行にあるセグメンテーション違反です。

スネークメンバー関数:

void setValue(Some value here...) {this-> value = input)

グローバル配列を外部化したファイルからの呼び出し:

snakes[0].setValue(some value here...)
4

1 に答える 1

3

配列の名前はポインタではありません。ほとんどの場合、それはポインターに減衰しますが、そうでない場合はそうではありません。だからあなたが持っているなら:

Snake snakes[8];

1つのソースファイルで

extern Snake *snakes; // don't do this

別の方法では、クラッシュを含むあらゆる種類の不思議な問題が発生します。配列の場合、extern宣言は配列を宣言する必要があります。

extern Snake snakes[];

ちなみに、私は何年も前にまったく同じ問題を抱えていたのでこれを知っています、そしてそれは私がこれを行う方法を考え出したときです。

于 2012-10-13T18:20:30.593 に答える