1

だから私はVS 2008で組み込み環境(ARMプロセッサ)用のC ++を使用しています。私は会社のために中規模のプロジェクトを構築しました。これまでは Windows アプリケーションでした。コンソール アプリケーションに変更するように依頼されたのは、このアプリケーションにとってより理にかなっているからです。Windowsアプリケーションにする本当の理由はありませんでした...最初は、VSで適切な設定を変更して(と思います)、再構築しました。正常にビルドされましたが、プログラムを実行しようとするたびに、タイトルに引用されている例外が発生しました。コンソール アプリケーションに切り替える前に、プログラムが完全に機能していたことを強調したいと思います。ソリューション全体の完全なクリーンアップと再構築も行いました。

これはおそらく手動で設定を変更しただけの問題だと思ったので、コンソールアプリに設定された新しいプロジェクトを作成し、ソース/その他の関連プロジェクトをすべてそれに接続しました。ソリューション内のさまざまなプロジェクトをすべて正しくリンクすると、これも問題なくビルドされますが、同じエラーが発生します。

プログラムがクラッシュすると、次のメソッドの挿入コマンドで停止します。

template<class Elem>
Node<Elem>* Node<Elem>::addChild(const Elem& value)
{
    Node<Elem>* newNode = new Node(value);
    newNode->m_pParentNode = this;
    m_childList.push_back(newNode);
    m_sNodeSet.insert(newNode);
    return newNode;
}

m_sNodeSet は、ツリー内の各ノードが一意でなければならないという規則を適用するために存在します。この addChild メソッドが最初に呼び出されたときにエラーが発生します。この時点で、m_sNodeSet のサイズは 0 であり、メモリを割り当てる必要があります。しかし、スローされた例外は Access Violation であり、予想される Bad Alloc ではありません。挿入ステートメントの前に m_sNodeSet.get_allocator().allocate(5) を追加して、それが何かを行うかどうかを確認しようとしましたが、同じ例外がスローされます。m_sNodeSet は、それが違いを生む場合、静的メンバー変数です。

この Node クラスは、私が作成したカスタム ツリー オブジェクトです。このツリー プロジェクトでは何週間も変更を加えていませんが、問題なく動作しています。このツリー プロジェクトに、これまで見たことのない、完璧に機能するものを投げかけているとは思わないので、ツリー プロジェクト自体に問題があるとは思いません。

これは、ライブラリの境界を越えて STL コンテナーにアクセスすることの問題でもないと確信しています。このエラーは、単一の静的ライブラリの操作内で発生しています。

これを適切に機能させるには、ソリューションでまだ変更する必要がある設定が必要だと思います。ソリューションには、1 つの DLL、1 つの LIB、および 1 つの EXE という複数のプロジェクトがあります。ツリーは 4 番目のプロジェクトですが、そのプロジェクトは単に適切なプロジェクトの「追加のインクルード」に入れられます。コンソール アプリとして実行されるように、EXE のみを変更しました。

ここで何が問題になる可能性があるのか​​ について何か気になることがあれば、それは大歓迎です.

4

1 に答える 1

1

宣言した場合:

// Global scope
// > (quote)The m_sNodeSet is a static member variable,
std::set<Node<Elem>*>   Node<Elem>::m_sNodeSet;

個人的なメモ:m_通常、プレフィックスはメンバー変数のドナーです (静的メンバーではありません)。したがって、この接頭辞を使用すると、多くの人を混乱させることになります。

m_sNodeSetが静的メンバーであり、上記のコードがmain の前に実行されている場合、初期化順序に問題がある可能性があります。これを解決するのは簡単です (以下を参照)。そうしないと、メモリが破損します。

class Node
{

    // Remove this line
    // static std::set<Node*>   m_sNodeSet;
    // Replace with this code
    static std::set<Node*>&  getNodeSet()
    {
        static std::set<Node*>   sNodeSet;
        return sNodeSet;
    }
    // Replace all references to m_sNodeSet with getNodeSet()
}

これは、メソッド内getNodeSet()で変数sNodeSetが静的であるため、最初の使用時に作成され、プログラムの長さにわたって存続するためです。各呼び出しは、同じオブジェクトへの参照を返します。最初の呼び出しで作成されるため、使用ポイントに返されたときに有効である (および完全に構築されている) ことが保証されます。

于 2012-04-18T16:31:55.340 に答える