vector でヒープメモリが壊れてしまいますが直し方がわかりません

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
marubu-
記事: 4
登録日時: 11年前

vector でヒープメモリが壊れてしまいますが直し方がわかりません

#1

投稿記事 by marubu- » 11年前

はじめまして
ヒープメモリが壊れるというバグが直せなくて困っています。

opencvで輪郭検出をするコードを実装したいのですが、findContours関数でvector<vector<cv::Point>> contours に輪郭を格納したところ、ヒープメモリが壊れてしまうようです。
vector の仕様では確保したメモリをオーバーすると自動的にさらに大きな領域を確保してくれるようですが、うまいこと確保できていないようです。
なにがだめなのかよくわかりません。ご教授願います。

コードを以下に示します。

コード:

    cv::Mat srcimg;
    srcimg =cv::imread("fish0811.jpg");
    cv::imshow("image",srcimg);


    cv::Mat grayimg;
    cv::cvtColor(srcimg,grayimg,CV_BGR2GRAY);


    const double lthreshold = 100.0;
    const double maxvalue = 255.0;
    cv::Mat binimg;
    cv::threshold(grayimg,binimg,lthreshold,maxvalue,THRESH_BINARY);


    std::vector< std::vector<cv::Point> > contours;
    
    cv::findContours(binimg,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);


    cv::Mat contourimg(srcimg.size(),CV_8UC1,cv::Scalar(255));
    int drawAllContours =-1;
    cv::drawContours(contourimg,contours,drawAllContours,Scalar(0));
    cv::drawContours(srcimg,contours,drawAllContours,Scalar(0));
    cv::imshow("contourimg",contourimg);
    cv::imshow("contour srcimg",srcimg);


    cv::waitKey(0);
    cv::destroyAllWindows();
足りない情報があれば載せますので、よろしくお願いします。

sleep

Re: vector でヒープメモリが壊れてしまいますが直し方がわかりません

#2

投稿記事 by sleep » 11年前

コードをコピーさせていただいて実行してみました。
私の環境では marubu-さんのコードで普通に動作しました。
エラーは出てません。

[環境]Windows7, VS2013update3, opencv2.4.9

コード:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

//#pragmaによるライブラリのリンク
//-----------------------------
//http://1drv.ms/1fxm0ef の v2.4.9/opencv_lib.hpp
#include <opencv2/opencv_lib.hpp>
//-----------------------------

int main()
{
	cv::Mat srcimg;
	srcimg = cv::imread("fish0811.jpg");

	//エラー処理を追加
	//-----------------------------
	if (srcimg.empty())
	{
		printf("jpgファイルの読み込み失敗\n");
		return -1;
	}
	//-----------------------------

	cv::imshow("image", srcimg);


	cv::Mat grayimg;
	cv::cvtColor(srcimg, grayimg, CV_BGR2GRAY);


	const double lthreshold = 100.0;
	const double maxvalue = 255.0;
	cv::Mat binimg;
	cv::threshold(grayimg, binimg, lthreshold, maxvalue, cv::THRESH_BINARY);


	std::vector< std::vector<cv::Point> > contours;

	cv::findContours(binimg, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);


	cv::Mat contourimg(srcimg.size(), CV_8UC1, cv::Scalar(255));
	int drawAllContours = -1;
	cv::drawContours(contourimg, contours, drawAllContours, cv::Scalar(0));
	cv::drawContours(srcimg, contours, drawAllContours, cv::Scalar(0));
	cv::imshow("contourimg", contourimg);
	cv::imshow("contour srcimg", srcimg);


	cv::waitKey(0);
	cv::destroyAllWindows();
}
一度OSを再起動して、試されてはいかがでしょう?
稀に物理的にメモリが壊れているわけではありませんが、
OSを再起動まで同じ現象を繰り返すことを前に経験したことがあります。

何度OSを再起動しても同じ現象になるのは、ちょっと分からないですね。
コード自体は問題なさそうです。

sleep

Re: vector でヒープメモリが壊れてしまいますが直し方がわかりません

#3

投稿記事 by sleep » 11年前

あー・・
一部、THRESH_BINARY と Scalar に cv:: を付けさせていただきましたが
それ以外はオリジナルのはずです。

THRESH_BINARY と Scalar に cv:: 付けてなくてコンパイル通っていましたか?

marubu-
記事: 4
登録日時: 11年前

Re: vector でヒープメモリが壊れてしまいますが直し方がわかりません

#4

投稿記事 by marubu- » 11年前

返信ありがとうございます。
再起動をかけてビルドしてみましたが、それでもやはりエラーが出てしまいます。
cvは一応namespace を使っていたのですが、書き忘れてしまいました。すいません。
ビルドは問題なく通ります
ちなみにエラーがでるのは、写真を表示しているウィンドウを消したあとで、強制終了されてしまいます。
デバッガを使用してヒープメモリが壊れてしまっているというメッセージが出てきました。
おそらくstd::vector< std::vector< cv::Point> > contours でヒープメモリを破壊しているのだと思いますが、drawContours関数で輪郭を描画できていて、その画像もちゃんと表示されます。


コード自体に問題はないようですね。
すると、環境が良くないのでしょうか。

こちらのPCのスペックは Windows7 professional ,intel corei7 3.50GHz, メモリは16GBで
プログラミング環境としてはVisual Studio C++ Compiler 10.0 (x86) ,Qt 4.8.6, OpenCV2.4.7です。

なにか試したほうがいいことなどありましたら、教えていただけたら幸いです。

marubu-
記事: 4
登録日時: 11年前

Re: vector でヒープメモリが壊れてしまいますが直し方がわかりません

#5

投稿記事 by marubu- » 11年前

もうひとつ似たようなコードがあるのですが、
そちらでは、ビルド後にウィンドウを消した瞬間に
Expression: _CrtIsValidHeapPointer(pUserData)というデバッグエラーが出てきます。

参考になるかわかりませんが、一応コードを載せておきます。

コード:

 const char *imagename = "fish0811_00.jpg";
      const int contour_index =  1;
      const int max_level = 0;
      cv::Mat src_img = cv::imread(imagename, 1);
      //if(src_img.empty()) ;

      // 2値化
      cv::Mat gray_img, bin_img;
      cv::cvtColor(src_img, gray_img, CV_BGR2GRAY);
      cv::threshold(gray_img, bin_img, 0, 255, cv::THRESH_BINARY|cv::THRESH_OTSU);

      /// 輪郭の検出
      std::vector<std::vector<cv::Point> > contours;
      std::vector<cv::Vec4i> hierarchy;
      // 2値画像,輪郭(出力),階層構造(出力),輪郭抽出モード,輪郭の近似手法
      cv::findContours(bin_img, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

      std::cout << "contour index = " << contour_index << std::endl;
      std::cout << "max level = " << max_level << std::endl;
      std::cout << "num of contours = " << contours.size() << std::endl;

      /// 輪郭の描画
      // 画像,輪郭,描画輪郭指定インデックス,色,太さ,種類,階層構造,描画輪郭の最大レベル
      cv::drawContours(src_img, contours, contour_index, cv::Scalar(0, 0, 200), 3, CV_AA, hierarchy, max_level);

      cv::namedWindow("Contours", CV_WINDOW_AUTOSIZE|CV_WINDOW_FREERATIO);
      cv::imshow("Contours", src_img);
      cv::waitKey(0);

marubu-
記事: 4
登録日時: 11年前

Re: vector でヒープメモリが壊れてしまいますが直し方がわかりません

#6

投稿記事 by marubu- » 11年前

すいません。解決いたしました。
opencvのライブラリを2.4.7から2.4.9に変えてみたら、エラーがでなくなりました。
ライブラリに問題があったようです。

sleepさま
助言いただきありがとうございました。

また、たびたびお世話になると思いますがそのときはよろしくお願いいたします。

閉鎖

“C言語何でも質問掲示板” へ戻る