0

プログラムでヒープ破損の問題が発生しています。プログラムでは、データのブロックを読み取り、それに FFT と IFFT を実行しています。マスターとスレーブの2つのイメージでやっています。まったく同じコードがマスターに対しては正常に機能しますが、スレーブ バッファーを削除しようとすると、スレーブ ファイルのヒープの破損が表示されます。

fcomplex は次のように定義されます。

typedef struct {float real, imag;}fcomplex;

コードの関連部分のスニペットが添付されています: 完全なコード: http://sharetext.org/7xXe

スレーブ イメージに対して fft および ifft 関数を呼び出さない場合、エラーは発生しません。(ただし、マスターにとってはすべて正常に機能します)

エラーをデバッグするためにアプリケーション検証ツールをインストールしましたが、ログ ファイルをデコードできませんでした。ここにあります: http://sharetext.org/Y2ji (XML ファイルのコピーを貼り付けたもの)

ビジュアル スタジオが与えるエラーは次のとおりです。

CCoarseFun::fcomplex * slave_bfr;
CCoarseFun::fcomplex * slave_col;


slave_bfr = Pcoarse.init_1Dcmplx(SIZE*s_cols); 
slave_col = Pcoarse.init_1Dcmplx(SIZE);

Pcoarse.cfft1d_(&SIZE,slave_col,&FFTdir); // This function causes a problem
Pcoarse.complex_mult_col(filter, slave_col, SIZE, slave_col)
Pcoarse.cfft1d_(&SIZE,slave_col,&FFTdir); // As does this one

// delete memory related to slave
delete [] slave_bfr;    // Heap corruption here
delete [] slave_col;

私を困惑させているのは、コードが非常に単純で、マスター ファイルに対してのみ 100% 機能することです。スレーブがクラッシュするのはなぜですか?

アプリケーション検証ツールの使用方法に関するソリューションまたはチュートリアルを案内してくれる人がいますか?

ありがとう、ショーナク

編集: Win7 x64 の使用 - VS2010

編集 2: init_1Dcmlx の定義

CCoarseFun::fcomplex* CCoarseFun::init_1Dcmplx(int n)
{
  fcomplex *a;
  a=new fcomplex[n];
  for(int i=0;i<n;i++)
  {
    a[i].real=float(0.0);
    a[i].imag=float(0.0);
  }
  return a;
}

EDIT3: cfft1D_ のコード: http://sharetext.org/hzIg

EDIT4: mem.delfloat() のコード

void CMemAlloc::del_float(float *a)
{
  if (a!=NULL)
  {
    delete[] a;
    a=NULL;
  }
  else
  {
    return;
  }
}
4

3 に答える 3

1

mem_float() 関数が正しくありません。削除後にポインターを NULL に設定しているように見えますが、ポインターのコピーでのみ機能しているため、呼び出し元のコピーは削除されたメモリ ブロックを指しています。

あなたはただすることができます

delete [] cf;
cf = NULL;

次のような行がいくつかあります。

four1(cf-1,nn,isign);

これは、配列の先頭より前にメモリにアクセスしていると思います。

これを超えて、内部のインデックス作成four1()は非常に複雑です。エッジケースを確認するには、デバッガーを使用してステップスルーする必要があります。

于 2012-08-28T08:30:33.807 に答える
0

まず、ヒープ破損エラーが何を伝えているのかを理解することが重要です。Visual Studio でデバッグ ビルドを実行すると、デバッグ ヒープを持つランタイム ライブラリのデバッグ バージョンが使用されます。メモリを割り当てるときはいつでも、newその両側にいくつかの余分なガードバイトがあります。deleteデバッグ ヒープは、ガード バイトが損なわれていないことを確認し、そうでない場合はこの警告を発行します。

がヒープにメモリを割り当てると仮定すると、Pcoarse.init_1Dcmplx()それへの 2 つの呼び出しはメモリを順番に割り当てる可能性が高くなります。

XXXXXX - guard bytes
slave_bfr
XYXYXY - these are the guard bytes that are probably being corrupted
slave_cols
XXXXXX

で操作Pcoarse.cfft1d_()を実行しslave_colsますが、削除時にヒープ破損エラーが発生しますslave_bfrcfft1d_()これは、が の開始前にメモリを上書きslave_colsしているため、 のガード バイトが破損していることを示唆していますslave_bfr

したがって、cfft1d_()負の配列インデックスを持つ可能性のある場所をコードで調べます。これにより、メモリslave_bfrが踏みつけられる可能性があります。

また、デバッグ ヒープを最大限に活用する方法に関する有用なヒントを含むSO の回答のいくつかを確認してください。特に、より集中的なメモリ チェックを有効にする方法に関するものです。

于 2012-08-28T08:22:26.537 に答える
0

「ヒープ破損が検出されました: 0x062C0040 の通常のブロック (#194456) の後」は、ブロックを割り当て、アドレス 0x062C0040 のブロック #194456 を取得し、割り当てたよりも多くのメモリ バイトを書き込んだことを示しています。したがって、古典的なバッファオーバーフローがあります。ポインターを STL コンテナーに置き換えることを検討する必要があります。std::vectorあなたの場合、で割り当てられた生の float 配列よりも使用することを好みますnew float[]。STL コンテナーは、メモリ ブロックを削除した後だけでなく、間違ったアクセスですぐに境界を越えた書き込みを検出するのに役立ちます。

于 2012-08-28T08:55:15.613 に答える