关于堆资源释放的问题:Debug Error! ... HEAP CORRUPTION DETECTED:

direction917 2011-02-22 12:24:48
Debug Error! ... HEAP CORRUPTION DETECTED:after normal block(....)
CRT detected that the application wrote to memory after end of heap buffer.

我的程序里有很多 class * object = new class(....),这样生成对象的方式,是不是堆资源的申请超过了堆的大小。那我应该怎样释放呢?

各位能不能帮我看下代码。主要是有三个类。
(为了明了,我只粘构造,析构有关的函数,其它的就不粘了)。

Array类:
[code=C]/C++
template<typename T>
class Tools;

template<typename T>
class Array{
protected:
T * data;
int total;
public:
friend class Tools<T>;

Array();
Array(int);
Array(const Array<T>&);

void initialize(int);
void dellocate();

T &operator() (int) const;// getter
void operator() (int,T);// setter
Array<T>& operator = (const Array<T>&);

int getTotal() const;

~Array(){
dellocate();
}
};

template<typename T>
Array<T>::Array():total(0),data(0){}

template<typename T>
Array<T>::Array(int total)
{
this->total = total;
data = new T[total];
};

template<typename T>
Array<T>::Array(const Array<T>& arr)
{
total = arr.getTotal();
data = new T[total];
for(int i=0; i<total ; i++)
data[i] = arr(i);
}

template<typename T>
void Array<T>::initialize(int n)
{
this->total = n;
data = new T[total];
}

template<typename T>
void Array<T>::dellocate()
{
if(data!=0)
{
delete[] data;
data=0;
}
}

template<typename T>
Array<T>& Array<T>::operator=(const Array<T>& arr)
{ if(this!=&arr)
{
this->~Array();
new(this)Array<T>(arr);
}
return *this;
}

[/code]
Matrix_1D 类
[code=C]/C++
template<typename T>
class Tools;

template<typename T>
class Matrix_1D : public Array<T>
{
private:

public:
friend class Tools<T>;

Matrix_1D();
Matrix_1D(int);
Matrix_1D(const Matrix_1D<T> &);

void initialize(int);
void dellocate();

T operator()(int) const;//gettter
void operator()(int,T);//setter

Matrix_1D<T>& operator=(const Matrix_1D<T>&);

~Matrix_1D(){
//dellocate();
};

};

template<typename T>
Matrix_1D<T>::Matrix_1D():Array<T>(){}

template<typename T>
Matrix_1D<T>::Matrix_1D(int total):Array<T>(total){}

template<typename T>
Matrix_1D<T>::Matrix_1D(const Matrix_1D<T> & matrix):Array<T>(matrix)
{}

template<typename T>
void Matrix_1D<T>::initialize(int total)
{
Array<T>::initialize(total);
}


template<typename T>
void Matrix_1D<T>::dellocate()
{
Array<T>::dellocate();
}

template<typename T>
Matrix_1D<T>& Matrix_1D<T>::operator=(const Matrix_1D<T>& matrix)
{
/*(for(int i=0; i<total ; i++)
{
this->operator()(i,matrix(i));
}*/
Array<T>::operator =(matrix);
return *this;
}

[/code]

Matrix_2D 类,与Matrix_1D类似,只是用存储二维的数据。
[code=C]/C++
template<typename T>
class Tools;

template<typename T>
class Matrix_2D : public Array<T>
{
private:
int height;
int width;
public:
friend class Tools<T>;

Matrix_2D();
Matrix_2D(int); //total
Matrix_2D(int, int); //height , width
Matrix_2D(const Matrix_2D<T> &);

void initialize(int);
void initialize(int,int);
void dellocate();

int computeLinearIndex(int,int) const;

T operator()(int,int,bool,bool) const; //getter, with bool parameter
T operator ()(int) const;
void operator()(int,T);//setter and bool = true
void operator()(int,int,T);

void operator+=(const Matrix_2D<T>&);
void operator-=(const Matrix_2D<T>&);
Matrix_2D<T>& operator=(const Matrix_2D<T>&);
friend Matrix_2D operator * (const Matrix_2D<T>& , const Matrix_2D<T>&);

int getHeight()const;
int getWidth()const;
int getTotal()const;
void fill(T);
void show(int starty,int endy ,int startx,int endx); //starty,startx,endy,endx
~Matrix_2D()
{
//dellocate();
}
};

template <typename T>
Matrix_2D<T>::Matrix_2D():height(0),width(0),Array<T>(){}

template <typename T>
Matrix_2D<T>::Matrix_2D(int t):height(1),width(t),Array<T>(t){}

template <typename T>
Matrix_2D<T>::Matrix_2D(int h , int w):height(h),width(w),Array<T>(h*w){}

template <typename T>
Matrix_2D<T>::Matrix_2D(const Matrix_2D<T> & matrix):height(matrix.getHeight()),width(matrix.getWidth()),Array<T>(matrix){}

template <typename T>
void Matrix_2D<T>::initialize(int total)
{
this->height=1;
this->width=total;
Array<T>::initialize(total);
}

template <typename T>
void Matrix_2D<T>::initialize(int height , int width)
{
this->height=height;
this->width=width;
Array<T>::initialize(height * width);
}


template <typename T>
void Matrix_2D<T>::dellocate()
{
height = 0 ;
width = 0;
Array<T>::dellocate();
}


template <typename T>
Matrix_2D<T>& Matrix_2D<T>::operator=(const Matrix_2D<T>& matrix)
{
height = matrix.getHeight();
width = matrix.getWidth();
Array<T>::operator =(matrix);
return *this;
}

[/code]

在实际的应用中,我会产生好多的Matrix_2D<float>对象(用于滤波),并用Array<Matrix_2D<float>>存储他们。举例一个函数
Array<Matrix_2D<float>> textonFilters(.....) //用于计算纹理的滤波器。
{
for(.......)
{1. 生成 Matrix_2D<float> 对象
2. 利用Array<Matrix_2D<float>>对象 存储.
}
返回Array<Matrix_2D<float>> 对象
}

还有一种情况是,类似于对象传递的函数,这样的函数应该如何清理堆空间? 例如:
Array<Matrix_2D<float>> filters(.....)
{
return textonFilters(....)
}

非常希望各位前辈明示下,我这里应该怎样释放堆空间,以解决最上面的问题。
这个代码已经经过了好多csdn朋友的帮助,非常感谢。不过还是要麻烦大家。
...全文
603 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
noock 2011-02-22
  • 打赏
  • 举报
回复
可能是数组越界,或者delete指针不合法(建议每次delete所把指针置成NULL),或者 new,new[]与delete,delete[]不匹配
direction917 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 ptrunner 的回复:]
因为没有返回当前内存而使用了之前对象内存,这就会很有可能致使内存越界。
不过解决就好,恭喜:)


引用 9 楼 direction917 的回复:

引用 7 楼 ptrunner 的回复:
源码?


引用 5 楼 direction917 的回复:

引用 3 楼 pengzhixi 的回复:
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往……
[/Quote]

虽然没有理解到你那样的深度,但是大概明白了。
就是由于对于没有经过内存分配的对象进行操作,造成的越界。是吧?
pstrunner 2011-02-22
  • 打赏
  • 举报
回复
因为没有返回当前内存而使用了之前对象内存,这就会很有可能致使内存越界。
不过解决就好,恭喜:)

[Quote=引用 9 楼 direction917 的回复:]

引用 7 楼 ptrunner 的回复:
源码?


引用 5 楼 direction917 的回复:

引用 3 楼 pengzhixi 的回复:
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往堆内存里写数据的时候是否有越界的行为

我感觉是我对一个矩阵的定义出了问题。能不能帮我看下?(构造函数等都如上)
Matrix_2D<Matrix_1D<f……
[/Quote]
direction917 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 ptrunner 的回复:]
源码?


引用 5 楼 direction917 的回复:

引用 3 楼 pengzhixi 的回复:
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往堆内存里写数据的时候是否有越界的行为

我感觉是我对一个矩阵的定义出了问题。能不能帮我看下?(构造函数等都如上)
Matrix_2D<Matrix_1D<float>> dst(src.getHeigh……
[/Quote]
我把问题解决了,是因为Matrix_2D的operator(int) 问题。
原来的函数是:
template<typename T>
T Matrix_2D<T>::operator()(int n) const
{
return data[n];
}
在进行dst(ind)时,并没有获得dst(ind)制定的对象,因为operator()(int n)返回的不是引用或者指针,把返回值改成引用就可以了。
非常感谢大家的帮助啊。
pstrunner 2011-02-22
  • 打赏
  • 举报
回复
你的initialize很简单,应该没有问题。

你屏蔽掉这段代码可以正常退出吗?
pstrunner 2011-02-22
  • 打赏
  • 举报
回复
源码?

[Quote=引用 5 楼 direction917 的回复:]

引用 3 楼 pengzhixi 的回复:
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往堆内存里写数据的时候是否有越界的行为

我感觉是我对一个矩阵的定义出了问题。能不能帮我看下?(构造函数等都如上)
Matrix_2D<Matrix_1D<float>> dst(src.getHeight() , src.getWidth());

for(int in……
[/Quote]
direction917 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ptrunner 的回复:]
如果楼主怀疑构造/析构有问题,可以屏蔽掉中间操作,仅仅保留堆内存分配与释放;

如果上面测试没有问题,就是你的中间操作有越界致使内存被破坏。
[/Quote]

我感觉是Matrix_2D<Matrix_1D<float>> dst(src.getHeight() , src.getWidth());

for(int ind = 0 ; ind<dst.getTotal() ; ind++)
dst(ind).initialize(textonfilters.getTotal());

这个的问题。
因为dst(ind)被没有被初始化成数组。
我该怎样修改?请高人明示。
direction917 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往堆内存里写数据的时候是否有越界的行为
[/Quote]
我感觉是我对一个矩阵的定义出了问题。能不能帮我看下?(构造函数等都如上)
Matrix_2D<Matrix_1D<float>> dst(src.getHeight() , src.getWidth());

for(int ind = 0 ; ind<dst.getTotal() ; ind++)
dst(ind).initialize(textonfilters.getTotal());
这样的目的是构造一个二维数组,数组的每个元素都是一个一维数组。
这样初始化后,赋值会出现HEAP CORRUPTION DETECTED的问题。
例如:dst(3)(2,5); //即将二维数组的第4个元素(按行)拿出来,将这个元素(是一维数组)的第3个元素赋值为5
这样初始化有什么样的问题?

pstrunner 2011-02-22
  • 打赏
  • 举报
回复
如果楼主怀疑构造/析构有问题,可以屏蔽掉中间操作,仅仅保留堆内存分配与释放;

如果上面测试没有问题,就是你的中间操作有越界致使内存被破坏。
pengzhixi 2011-02-22
  • 打赏
  • 举报
回复
如果我没记错,你就是昨天那个搞什么图像的朋友吧,你这里最好看看有没有在往堆内存里写数据的时候是否有越界的行为
direction917 2011-02-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 nocky 的回复:]
可能是数组越界,或者delete指针不合法(建议每次delete所把指针置成NULL),或者 new,new[]与delete,delete[]不匹配
[/Quote]
我的析构有问题么?
template<typename T>
void Array<T>::dellocate()
{
if(data!=0)
{
delete[] data;
data=0;
}
}


~Array(){
dellocate();
}

template<typename T>
void Matrix_1D<T>::dellocate()
{
Array<T>::dellocate();
}
~Matrix_1D(){

};


template <typename T>
void Matrix_2D<T>::dellocate()
{
height = 0 ;
width = 0;
Array<T>::dellocate();
}
~Matrix_2D()
{

}

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧