![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
Cで書いたコードを動かすと、ヒープが壊れてたというエラーが出るようになりました。
freeなどで、自分なりに調べてメモリを解放したつもりですが、
その後また再発するようになったので、すみません、どの変数をどう解放するべきか、アドバイスをいただけると助かります。OpenCVの関数を使っています。
内容は、Aというファイルに20枚のテンプレートBを当てて近似値をとり、それを1行の文字列にしてCSVに保存する、というものです。
======
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <string.h>
#define snprintf _snprintf
#include <errno.h>
#include <math.h>
int
main (void)
{
FILE *fp;
char str[60], str2[200], str3[200];
int i,ii;
double result[20];
CvFont font;
IplImage *src_img1, *src_img2, *src_img3;
IplImage *dst_img[1];
IplImage *fresh_img,*mask_img;
char *fname = "C:\\Documents and Settings\\...\\result.csv";
char kugiri[]=",";
result[ii]=NULL;
free(str2);
fp = fopen( fname, "w" );
if( fp == NULL ){
printf( "%sファイルが開けません\n", fname );
return -1;
}
//ファイルA=src_img1
src_img1 = cvLoadImage ("C:\\Documents and Settings\\...\\2.jpg", CV_LOAD_IMAGE_GRAYSCALE);
for (ii=0; ii<20; ii++) {
sprintf(str,"%s%d%s","C:\\Documents and Settings\\...\\",ii, ".png");
//ファイルB=src_img2
src_img2 = cvLoadImage (str, CV_LOAD_IMAGE_GRAYSCALE);
//テンプレートのファイルBを、比較用にコピーしています
dst_img[0] = (IplImage *) cvClone (src_img2);
//result[ii]には近似値が格納されます
result[ii] = cvMatchShapes (src_img1, src_img2, CV_CONTOURS_MATCH_I1, 0);
//ここで ↓ エラーが出るので、型がおかしいのかと直していたのですがヒープが壊れて直せなくなりました。str2に、近似値の結果+区切り文字(カンマ)をテンプレート枚数(20)回ループで回して文字連結して格納したいのです。近似値は小数点6ケタまであればいいので、floatでいいと思ったのですが違うでしょうか。
sprintf(str2,"%f%s",result[ii],kugiri);
if (ii==0){
sprintf(str3,"%s",str2);
return -1;
}
sprintf(str3,"%s%s",str3,str2);
//メモリの解放
cvReleaseImage(&src_img2);
cvReleaseImage(&dst_img[0]);
free(str2);
result[ii]=NULL;
printf("%f",str3);
}
fprintf(fp, "%s", str3);
fclose( fp );
free(str3);
return 0;
}
==
すみません、とても基本的なことなのだろうと思うのですが、ぜひ教えてください。
No.3ベストアンサー
- 回答日時:
他にも
> sprintf(str3,"%s%s",str3,str2);
出力領域と入力領域でstr3が被っています。
このような場合、どうなるかは未定義です。
期待通りに動くかもしれないし、まったく動かないかもしれないし、ハードディスクが初期化されるかもしれない。
単純に継ぐならstrcatを。
どうしてもsprintfを使うなら、別の領域(例: char str4[400];)を用意して
sprintf(str4,"%s%s",str3,str2);
strcpy(str3,str4);
等と直接str3へ出力しないようにします。strcatにくらべて無駄が多いですが。
Cで文字列を扱うときは、他言語ほど楽ではないということを覚えておきましょう。
これまでいろいろと指摘はありますが、「//ここで ↓ エラーが出るので」の箇所には指摘がありません。
これも、Cを扱う上で覚えておかないといけない点です。
・Cは最低限のことしかしない。
例えば、他の言語なら free(str2)に相当することをしようとしたら、「確保した領域ではない」等とエラーになるはず。でも,Cではそんなチェックはしない。
・そのため、プログラムが間違っていてもコンパイルに成功して、一見正常動作しているように見えることがある。
・その結果、変数が勝手に書き変わるなどの不具合が発生し、一見無関係に見えるところでエラーが発生することがある。
kmee様、いつもアドバイスくださってありがとうございます。
strcatに変えて、なんとか、エラーも出ず思う結果が出るようになりました。
いろいろと書いてくださったアドバイスをよく心得て勉強します。
特に、Cはコンパイルに成功したからといって安心してはいけないことを肝に命じます。
大変助かりました。
No.2
- 回答日時:
>double result[20];
>result[ii]=NULL;
この文を実行する時点で、iiの値が確定していないように見えます。
また、double型の変数result[]に、NULLというポインターを代入する
意味合いは、どの辺にあるんでしょうか?
何だかめちゃくちゃなことをやろうとしているように見えてしまいます。
なるほど、確定していないiiを"解放"したり、型違いのポインターを代入するなど、
めちゃくちゃなことが、もう一度調べてみてよくわかりました。
ありがとうございます。
気をつけます。
すぐに書き込んでくださったのに、お礼が遅くなりましてすみませんでした!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- JavaScript clear機能を失わずにファイルアップロード機能を作成したい 3 2023/06/10 16:12
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- Perl 画像が表示でnull; this.src 1 2022/04/19 11:31
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
#defineが使用するメモリ領域に...
-
VC++でSQLへSELECT文を送ったの...
-
構造体メンバの初期化
-
printf による16進表示について
-
空白を含んだ文字列がうまく格...
-
【C言語】全角文字の配列を、全...
-
reallocでエラー
-
至急お願いします!!
-
終了条件Ctrl+zについて,結果表...
-
プログラムの実行時に'<'でリダ...
-
「指定されたキャストは有効で...
-
マイナスからプラスへ転じた時...
-
信頼区間の1.96や1.65ってどこ...
-
プログラムでの数字につく”f”の...
-
C言語での引数の省略方法
-
2÷3などの余りについて
-
正負を反転させて出力するプロ...
-
DWORDの実際の型は何でしょうか
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Enterキーを押されたら次の処理...
-
C言語で複数列のデータを1列の...
-
printf による16進表示について
-
C言語のプログラムで、途中で止...
-
char型2つを結合し、short型に...
-
矢印キーを押下してコンソール...
-
#defineが使用するメモリ領域に...
-
【C言語】全角文字の配列を、全...
-
終了条件Ctrl+zについて,結果表...
-
空白を含んだ文字列がうまく格...
-
プログラミングの授業の課題です
-
リストの作成と出力(C言語)
-
c言語で文書を読み込み、単語の...
-
構造体メンバの初期化
-
エラーについて質問です。
-
reallocでエラー
-
C言語でのCSVファイルの読み出...
-
なぜ無限ループになるかが分か...
-
Cプログラムについて
-
C++で指定文字列のカウント方法...
おすすめ情報