• ベストアンサー

newとdeleteな気がするエラー

以下のようなプログラムを書いているのですが、delete [] ang;の行を実行すると、 Debug Assertion Failed! Program: ...\Debug\pro.exe File: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp Line: 52 Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) というエラーが発生します。 fscanfを書いてからうまくいかなくなってきたので、modtorがオーバーフローしてるのかな?とも思ったのですが、特にそれらしいものは見当たりません。 いったい何が原因なのでしょうか? よろしくお願いします。 #include<stdio.h> #include<string> using namespace std; void main(void){   int i;   int ret;   static const int anum=3;   static const int LoopMax=100;   double *modtor=new double[LoopMax*anum];   double *ang=new double[LoopMax*2*anum];   const string strlearned="A.csv";   const string strlearning="_learning.csv";   FILE *fpl;   FILE *fpvnmd;   errno_t err;   double outputv[anum]={0};   double tempd;   double *tarr=new double[LoopMax];   //delete [] tarr;      //ここで消すとエラーが消える   fopen_s(&fpl,strlearned.c_str(),"r");   printf("データ読み込み\n");   for(i=0;i<LoopMax;i++){     if(fscanf(fpl,"%[^,],%lf,%lf,%lf,%lf",&tempd,&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2])==EOF)break;   }   fclose(fpl);     delete [] ang;   delete [] tarr;   delete [] modtor; }

質問者が選んだベストアンサー

  • ベストアンサー
  • php504
  • ベストアンサー率42% (926/2160)
回答No.4

>この意味を余りよく知らないのです^^; これが原因なので意味を理解しないまま使ってはだめでしょう。 %[~]は文字列を読み込む指定子の1つです。(普通は%sですね) フォーマット系の可変引数の関数では引数の型チェックができません。 フォーマット指定子と実際の引数の型を合わせるのはプログラマの責任で型が合わないとこのようなバグを引き起こします。 >この「*」は何を意味しているのでしょうか? http://www.linux.or.jp/JM/html/LDP_man-pages/man3/scanf.3.html より引用 ------------------- 代入抑制文字"*"。 scanf() は変換指定に指示された通り入力を読み込むが、その入力は捨てられる。対応する pointer 引き数は必要なく、 scanf() が返す代入が成功した数にこの指定は含まれない。 ------------------- です。

glarelance
質問者

お礼

よく分かりました。 どうも有り難うございました。

その他の回答 (4)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.5

4. 「元のままだと「5番目の引数が無いので、」とありますが、もとの場合、5番目の引数は、「&modtor[anum*i+1]」となっていると思うのですが、これはどういう意味なのでしょうか? フォーマット指定部分"%[^,],%lf,%lf,%lf,%lf"では5個の指定がありますが読み込む変数が &tempd &modtor[anum*i] &modtor[anum*i+1] &modtor[anum*i+2] の4個しかないということでしょう。 今回は個数の問題だけでもなく1個目の型があってないのも原因ですが。 データが 0.000000,0.000000,0.010127,0.210067 なら fscanf(fpl,"%lf,%lf,%lf,%lf",&tempd,&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2]) でも問題なかったのでは。

  • jmh
  • ベストアンサー率23% (71/304)
回答No.3

その「http://simd.jugem.jp/?eid=49」には「%[^,] を使用することにより、カンマ以外の_文_字_列_を読み込むという_指_定_が出来るわけです。」とありますが?

glarelance
質問者

お礼

あ、、、 文字列用の特殊指定子だったんですね。。。 どうも有り難うございました。

  • jmh
  • ベストアンサー率23% (71/304)
回答No.2

%[^,] に対して double tempd でいいの?

glarelance
質問者

お礼

>%[^,] に対して double tempd でいいの? これは、どういう意味なのでしょうか? 実は、%[^,]はhttp://simd.jugem.jp/?eid=49 に、こう書くとカンマを無視して読み込めるようになると書いてあったから、付けただけなもので、この意味を余りよく知らないのです^^;

回答No.1

if(fscanf(fpl,"%[^,],%lf,%lf,%lf,%lf",&tempd,&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2])==EOF)break; を if(fscanf(fpl,"%*[^,],%lf,%lf,%lf",&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2])!=anum)break; にしてみよう。 「scanfは引数が足りなくても知ったこっちゃない」と「scanfは読み捨て可能」と、2つの事を覚えましょう。 元のままだと「5番目の引数が無いので、メモリ上にあったゴミをアドレスだと思って、そこに実数値を格納し、メモリがグチャグチャに壊れる」とか「カンマ以外を読み捨てる時、読み捨てるバイト数がdoubleオブジェクトのサイズを超えてたら、メモリがグチャグチャに壊れる」って事が起きます。 つか、 >  //delete [] tarr;      //ここで消すとエラーが消える の状態で実行時エラーが出ないで動いちゃうのが不思議。偶然「壊れても構わないメモリが壊れているだけ」なんだろうなあ。

glarelance
質問者

お礼

解答有り難うございます。 if(fscanf(fpl,"%*[^,],%lf,%lf,%lf",&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2])!=anum)break; について、いくつか質問があります。 1. 「%*[^,]」という記述がありますが、この「*」は何を意味しているのでしょうか? 2. 「scanfは引数が足りなくても知ったこっちゃない」と「scanfは読み捨て可能」とのことですが、ここでいう引数とは、「,&modtor[anum*i],&modtor[anum*i+1],&modtor[anum*i+2]」の部分のことを指しているのでしょうか? また、私は、一列目の値を「,&tempd」で空読みするようにしてみていたのですが、chie65535さんの方では、この部分がなくなり、%lfの数も3つになっていますが、このことに関係しているのでしょうか? もしそうなら、どのように関係しているのでしょうか? 3. chie65535さんは、fscanfの戻り値が、anumでなければ終了としていますが、これは行の項目数が3でなければ、想定している項目数と違うから終了。という解釈で良いんでしょうか? 4. 「元のままだと「5番目の引数が無いので、」とありますが、もとの場合、5番目の引数は、「&modtor[anum*i+1]」となっていると思うのですが、これはどういう意味なのでしょうか? 私の疑問は、どういうデータファイルを読み込んでいるのか、書き忘れてたから出ている部分もあるのかな・・・ 私が使っているデータは、 0.000000,0.000000,0.010127,0.210067 0.010000,0.000000,0.059026,0.178709 0.020000,0.000000,0.096992,0.153418 ・ ・ ・ 0.990000,0.000000,-0.020241,0.019949 という、100行のデータになっています。 長々となってしまいましたが宜しくお願いします。