2

動的にリンクされたライブラリが、オーバーロードされたオペレーター delete を呼び出しているのに、オペレーター new を呼び出していないことに問題があります。私のexeは次のようになります。

class A {
public:
    void func() {
        t = dynLib::Type::CreateObject();
    }
    dynLib::Type t;
};

void main() {
    A a;
    a.func();
}

そして、静的にリンクされたライブラリがあり、グローバルなオーバーロードされた演算子と、問題を引き起こしている動的にリンクされたライブラリがあります。基本的に何が起こるかというと、dynLib::Type 型には、コンストラクターに要素を追加する std::vector が含まれています。したがって、タイプは次のようになります

class Type {
public:
    Type() {
        v.push_back( T() );
    }

    std::vector< T > v;
};

func() が呼び出されると、Type の新しいインスタンスが作成され、値によって渡されてから t に割り当てられます。そこで動作する operator= は、std::vector にもその operator= を介してコピーします。これは、コンストラクターに要素が既に追加されているため、t の古い std::vector で deallocate を呼び出します。この割り当て解除呼び出しは、最終的にオペレーター delete を呼び出します。問題は、私の演算子 new が呼び出されなかったため、完全に異なるメモリ空間でポインタを削除していることです (メモリ ロギングがこれを示しています)。

今、私はおそらく何かが欠けているだけです。上記のクラス A は dynLib::Type オブジェクトを保持しているため、(スタティック ライブラリからの) new 演算子がリンクされる前に構築される可能性があります。それは可能ですか?構成された dynLib::Type のコンストラクターがどの時点で呼び出されるかはよくわかりません。動的ライブラリはデフォルトの stl アロケータを使用するため、ファンキーなことは何もしません。

exeに Type クラスを含めるだけで、動的にリンクされたライブラリを使用せずに同じ状況を再現しようとしました。ただし、これは問題の原因ではないため、リンクの順序に関係があるに違いないと私は信じています。

4

1 に答える 1

1

これは悪いことです。DLL の境界を越えて STL オブジェクトを実際に使用しています。これは大したことではなく、引き続き頭痛の種になります。リンクの問題の原因として最も可能性が高いのは、実行可能ファイルと DLL が CRT を使用する方法です。1 つが静的 (/MT) を使用し、もう 1 つが動的 (/MD) を使用している場合、あらゆる種類の奇妙さが見られます。オーバーロードされたオペレーターnewは、通常、最初にグリッチが発生します。

CRT が全面的に一貫している場合は動作するはずですが、それでも DLL を静的ライブラリであるかのように使用することはお勧めしません。

TypeDLL の外部で構築する必要がないようにコードをリファクタリングしてみてください。改善されるかどうかを確認してください。

于 2010-01-20T23:12:55.050 に答える