0

我在程序中遇到堆损坏问题。在程序中,我正在读取一个数据块并对其执行 FFT 和 IFFT。我正在为 2 个图像(主从图像)做这件事。完全相同的代码适用于主服务器,但当我尝试删除从属缓冲区时,显示从属文件的堆损坏。

fcomplex 定义为:

typedef struct {float real, imag;}fcomplex;

附上相关部分代码片段:完整代码:http ://sharetext.org/7xXe

如果我不为从映像调用 fft 和 ifft 函数,则不会发生错误。(不过对主人来说一切都很好)

为了调试错误,我安装了应用程序验证程序,但我无法解码日志文件。它在这里:http ://sharetext.org/Y2ji (XML文件复制粘贴)

视觉工作室给出的错误是:检测到堆损坏:在 0x062C0040 的正常块 (#194456) 之后

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_1Dcmplx 的定义

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()在堆上分配内存,那么对它的两次调用很可能会一个接一个地分配内存:

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

您在 上执行操作Pcoarse.cfft1d_()slave_cols但在删除时出现堆损坏错误slave_bfr。这表明它cfft1d_()在开始之前覆盖内存,slave_cols从而破坏slave_bfr.

因此,我会查看您的代码以cfft1d_()查找可能有负数组索引的地方,因为这可能会导致内存slave_bfr被踩踏。

还要检查一些SO 答案,其中包含有关如何充分利用调试堆的有用提示,特别有关如何启用更密集的内存检查的提示。

于 2012-08-28T08:22:26.537 回答
0

"Heap corruption Detected: after normal block (#194456) at 0x062C0040" says that you allocated a block, got the block #194456 with address 0x062C0040 and you wrote more memory bytes than you allocated. So you have a classical buffer overflow. You should consider replacing pointers with STL containers. In your case I'ld prefer using std::vector over a raw float array allocated with new float[]. The STL containers can help you detect writing beyond boundaries immediately at the wrong access, not only after deleting the memory block.

于 2012-08-28T08:55:15.613 回答