1

このプログラムで破損したヒープ エラーが発生する理由がわかりません (クラスに OpenCV を使用していますMat)。

class A {
    private:
    Mat image;      

    static UINT ThreadProc( LPVOID pParam ) {
        A* pThis= (ClientNetwork*)pParam;
        UINT nRet= pThis->DoThreadProc();     // get out of 'static mode'
        return( nRet );
    }
    UINT ClientNetwork::DoThreadProc() {
         vector<uchar> vect;
         while(1) {
             /**** initialize vect and get the image data to decode ****/

             decode(vect);
         }
    }

    public:
    void decode(const vector<uchar>& vectorData){image=imdecode(vectorData, CV_LOAD_IMAGE_COLOR);}
    Mat get_image(){return image;}
    void start() {m_pcThread= AfxBeginThread(ThreadProc, this );}
}

int main() {
    A* a = new A();
    a->start();
    while(1) {
        Mat image = a->get_image();
    }
    delete a;
    return 0;
}

Mat image = a->get_image();オブジェクトのコピーではなく参照を返すと、エラーが発生しなくなるため、エラーが発生したようです。

Mat* get_image(){return &image;}

Mat* image = a->get_image();

オブジェクトのコピーを返すことは、C++ では参照よりも洗練されていると読みました。だから私は何が間違っているのか知りたいです。

編集: Visual Studio は中断しa->decode(vect)ますが、参照ではなくオブジェクトを返す場合にのみ発生します。

編集 2: プログラム全体を反映するようにコードを編集しました。a問題は、コピーと変更が同時に行われる共有オブジェクトにあると思います。ミューテックスを使用して問題が引き続き発生するかどうかを確認します。

4

3 に答える 3

2

あなた自身が示唆したように、それはスレッド同期の問題です。画像は常にその無限のwhileループに入力されています。そして、その途中で、そのコピーを作成しようとします。災害のレシピ。各反復で、DoThreadProcのそのループ内で書き込みロックを取得する必要があります。次に、get_image内で読み取りロックを取得する必要があります。リーダーを飢えさせない読み取り/書き込みロックライブラリを使用する必要があります。

または、ミューテックス/クリティカルセクションを操作することもできます。書き込みループと読み取り(get_image)の両方が、作業中に画像への排他的アクセスを取得します。

しかし、私は興味があります-あなたのスレッドプロシージャは無限ループで物事をデコードしています。そこで何をしようとしていますか?そして、あなたはどのような画像を期待していますか?ループ反復のその時点での画像はありますか?

于 2013-03-11T06:00:39.733 に答える
2

初期化せずに使用aします。

int main() {
    A* a;
    vector<uchar> vect;
    while(1) {
        // get the vector of data
        a->decode(vect);

未定義の行動へようこそ、人口:あなた。

aより良い結果を得るために初期化します。

于 2013-03-11T04:09:41.983 に答える
1

のコピー コンストラクターはcv::Mat、イメージのディープ コピーを作成しません。オリジナルへの参照を作成し、Matその参照カウントを増やすだけです。クラスの次の関数では、returnステートメントはコピー コンストラクターを呼び出し、元の への参照を返しますimage。これが、ヒープ破損の原因と考えられます。

Mat get_image(){ return image; }

imageオリジナルimageが誤って変更されないように、次のように のディープ コピーを返す必要があります。

Mat get_image(){ return image.clone(); }
于 2013-03-12T05:17:52.483 に答える