0

私はクラスを持っています、それをビルダーと呼びましょう。プライベートメンバーが次のように宣言されています

vector< vector< Node >> buffers; // Node is a pure data class.

このBuilderクラスのコンストラクターでは、次のことを行います。

buffers = vector< vector< Node >>(amount);

ここで、「金額」は実行時にのみわかります。

ビルダークラスの存続期間中、いくつかの操作がバッファーメンバーで呼び出されます。私が使用している唯一の操作は次のとおりです。

buffers[i].push_back(Node());
buffers[i].clear();

参考までに、ここにアルゴリズムの要点を追加しています。

// REFINE BUFFERS
// check all levels (bottom up) and group 8 nodes on a higher level
for(int d = maxdepth; d >= 0; d--){
    if(buffers[d].size() == 8){ // if we have 8 nodes
        if(isBufferEmpty(buffers[d])){ 
            buffers[d-1].push_back(Node()); // push back NULL to represent 8 empty nodes
        } else { 
            buffers[d-1].push_back(groupNodes(octree, buffers[d])); // push back parent node
        }
        buffers[d].clear(); // clear the 8 nodes on this level
    } else {
        break; // break the for loop: no upper levels will need changing
    }
}

Builderクラスオブジェクトがスコープ外になると、オブジェクトは破棄され、クラスメンバーも破棄されます。VS2010デバッグモードの場合、問題はありません。リリースモードでは、「Windowsがブレークポイントをトリガーしました」というエラーが発生します。

問題は、_Destroy呼び出しでのSTL:vector仕様のこの部分にあります。

void _Tidy()
    {   // free all storage
    if (this->_Myfirst != 0)
        {   // something to free, destroy and deallocate it
        this->_Orphan_all();
        _Destroy(this->_Myfirst, this->_Mylast);
        this->_Alval.deallocate(this->_Myfirst,
            this->_Myend - this->_Myfirst);
        }
    this->_Myfirst = 0;
    this->_Mylast = 0;
    this->_Myend = 0;
    }

デバッガーを見ると、_Mylastの値が正しくない(0x000000000000)ことがわかります。これが、この割り当て解除が失敗する原因である可能性があります。最後にbuffers.clear()を実行しようとすると、同じ結果になります。(buffers [i] .clear()は正常に機能します)。また、「続行」を押すと、プログラムも正常に動作します。

実行後、アルゴリズムからいくつかの出力があります。表示されるのは、個々のベクトル内の要素の量と、buffers [i] .begin()およびbuffers [i] .end()によって示されるアドレスです。「メインバッファ」とは、buffers.begin()およびbuffers.end()を呼び出したときに取得する値を意味します。

  Main Buffer begin: 0000000002068050
  Main Buffer end  : 0000000002068130
  buffers[0] : 0 elements, 0000000002068160 - 0000000002068160
  buffers[1] : 0 elements, 0000000002070080 - 0000000002070080
  buffers[2] : 0 elements, 0000000002068E70 - 0000000002068E70
  buffers[3] : 0 elements, 0000000001F71810 - 0000000001F71810
  buffers[4] : 0 elements, 0000000002068BB0 - 0000000002068BB0
  buffers[5] : 0 elements, 00000000020688F0 - 00000000020688F0
  buffers[6] : 0 elements, 0000000002068370 - 0000000002068370

今私の質問は、どうすれば_Mylastを破損できたのでしょうか?(とにかく、どういうわけか、ヒープを破損しました)

この問題は、以前はグローバルスコープで定義された関数であったアルゴリズムをクラスに移動したときにのみ発生し始めました。C++がベクトルをクラスメンバーとして処理する方法に関係しているのではないかと思います。

私のビルダークラスは、ある量のバッファー(ベクターのもの)をセットアップし、ノードが生きている限り、これらのバッファーにノードをポップしてプッシュできるはずです。それが私が達成しようとしていることです。

4

2 に答える 2

3

がゼロのbuffers[d-1]場合でも書き込みます。dそれはあなたの問題でしょうか?範囲外エラーは、後になって (ベクトルの割り当てが解除されるときなどに) 検出されることがあります。

于 2012-10-29T20:35:08.873 に答える
0

Nodeオブジェクトをコピーして、その後正しく破棄できることを確認してください。非常によくある間違いは、含まれているオブジェクト (この場合Nodeは ) に、基になるすべてのデータの一意のコピーがあることに依存するデストラクタで何かを実行させることです。コピーのオーバーヘッドを防ぐために、代わりにバッファーに a を格納するshared_ptr<Node>か、少なくとも実装Node::Node(const Node &)Node::operator=(const Node &)たことを確認し、コピーのセマンティクスが正しいことを確認する必要がある場合があります (内部の生ポインターも同様に変更Nodeshared_ptrます)。

RAII の原則についても読みたいと思うかもしれません。これは、今後これらの間違いを防ぐのに役立ちます。

于 2012-10-29T20:44:33.997 に答える