2017-08-19 3 views
2

p_img1p_img2IplImage*以前cvLoad'ed、私はp_img1p_img2のコピーになりたいされています。 *p_img1 = *p_img2;を書くOpenCVの:なぜ* p_img1 = * p_img2が正しくない

が正常に動作するようです(私はだけでなく、画像を表示することで、デバッグモードでそれを確認することができます)、その行の後に点を除いて、1つのポインタにcvReleaseImageを使用すると、明らかに他のものを破壊します。 2つのポインタ(2つのアドレス)が異なるので、構造体のフィールドのみがコピーされるので、私はそれを理解しません。

p_img1 = cvCloneImage(p_img2);を使用すると問題が解決されています。

誰かがなぜ*p_img1 = *p_img2が間違っているのか説明してください。 cvCloneImage()はどういう意味がありますか?

+0

あなたは本当に非推奨のC APIを使用してはいけません。特に、質問をC++としてタグ付けした場合は特にそうです。 – beaker

+0

あなたはオブジェクトをコピーしますが、オブジェクトは、オブジェクトを破棄/解放するときに解放される可能性のある割り当てられたメモリへのメンバ変数ポインタを持っている可能性があります。これは、IplImageのような画像タイプの場合です。 cv :: Matには同じタスクの参照カウントがいくつかありますが、これは非常にうれしいです! – Micka

答えて

5

私はあなたにC++ポインタ関連の参考文献を読んでいただきたいと思います。

p_img1p_img2は、IplImage構造体へのポインタです。

  • p_img2
  • しかし、IplImage構造は、画像データが含まれていないimageheader2を指しimageheader1を指し

    • p_img1は、代わりに、ピクセル値を格納するメモリ位置へのポインタを保持します。

      • imageheader1がpixeldata1へのポインタを含む
      • imageheader2は

        • imageheader1は今にポインタが含まれているので、*p_img1 = *p_img2を実行

        は、p_img2に似p_img1の内容を行いますpixeldata2へのポインタが含まれていますピクセルデータ2

      • imageheader2にまだpixeldata2へのポインタが含まれています

      pixeldata1は参照されず、解放されないとメモリリークの可能性があります。解放するとき、cvReleaseImageはポインタ 'pointer of pointer'のパラメータをとります。実際にはポインタが指し示されているimageheaderを解放します。したがって、imageheader1とimageheader2の両方が無効なメモリを指します。

      cvCloneImageには、メモリ割り当てが組み込まれています。このメモリ割り当てでは、コンテンツをコピーする前に実際に新しいメモリブロックが割り当てられます。 p_img1 = cvCloneImage(p_img2)を実行すると、OpenCVは新しいメモリブロック(pixeldata3)を割り当て、pixeldata2(imageheader2が指し示すp_img2)からデータをコピーし、次にimageheader1(p_img1が指す)を更新します。

      • imageheader1
      • imageheader2をpixeldata3へのポインタを含むポインタを含むpixeldata2へ

      => pixeldata1が参照されていないこと、それが解放されていない場合、潜在的なメモリリークとなるであろう。

    関連する問題