C++ 删除堆上存储数据的对象
我的程序是使用SDL库中的类编写的 我有以下课程:C++ 删除堆上存储数据的对象,c++,memory-management,heap-memory,heap-corruption,C++,Memory Management,Heap Memory,Heap Corruption,我的程序是使用SDL库中的类编写的 我有以下课程: class s_group { private: SDL_Surface* image; unsigned int* F_total; float* F_length; SDL_Rect** F; float* F_current; unsigned int S_total; unsigned int S_current;
class s_group
{
private:
SDL_Surface* image;
unsigned int* F_total;
float* F_length;
SDL_Rect** F;
float* F_current;
unsigned int S_total;
unsigned int S_current;
public:
s_group(void);
virtual ~s_group(void);
bool setup( const char* filename, unsigned int s );
//other member functions
};
私有成员指针存储堆上声明的内存位置,由成员函数setup
分配
bool s_group::setup( const char* filename, unsigned int s )
{
s_group::~s_group();//delete already allocated heap memory
if(!load_file(image, filename))
{
image = NULL;
return false;
}
S_total = s;
F = new SDL_Rect*[S_total];
F_total = new unsigned int[S_total];
F_length = new float[S_total];
F_current = new float[S_total];
for(unsigned int index = 0; index < S_total; ++index)
{
F[index] = NULL;
F_total[index] = 0;
F_length[index] = 0.f;
F_current[index] = 0.f;
}
//loop for each array slot and set values of data
return true;
}
函数完成后,我调用delete
重新分配堆内存。删除这一行可以解决问题,但是会出现内存泄漏
delete sparkle;
sparkle = NULL;
这将调用类的析构函数,我认为由于内部使用了delete
操作符,在该类中会发生错误
s_group::~s_group(void)
{
SDL_FreeSurface(image);
image = NULL;
for(unsigned int s = 0; s < S_total; ++s)
{
for(unsigned int f = 0; f < F_total[s]; ++f)
{
F[s][f].x = 0;
F[s][f].y = 0;
F[s][f].w = 0;
F[s][f].h = 0;
}
delete[] F[s];
F[s] = NULL;
}
delete[] F;
F = NULL;
delete[] F_total;
F_total = NULL;
delete[] F_length;
F_length = NULL;
delete[] F_current;
F_current = NULL;
S_total = 0;
S_current = 0;
}
s_组::~s_组(无效)
{
SDL_自由曲面(图像);
image=NULL;
对于(无符号整数s=0;s
到达“删除”操作符时,会出现一个对话框,说明:
Windows已在Program.exe中触发断点。这可能是由于堆损坏,这表明Program.exe或其加载的任何DLL中存在错误
如何在不导致堆损坏的情况下删除此对象?来自
第9项:在构造或销毁期间,切勿调用虚拟函数。
您不应该在构造或销毁期间调用虚拟函数,因为这些调用不会按照您的想法执行,如果它们执行了,您仍然会不高兴。如果你是一个正在恢复的java或C程序员,请密切注意这个项目,因为这是一个地方,那些语言Zigg,而C++ +ZAG.<
事实上,即使您应该定义析构函数,强制调用它应该是不可能的我无法编译您的代码,但这里是 我注意到的第一件事是你打电话给你的析构函数。。你不会想那样做的!相反,创建一个释放函数并调用它 接下来我注意到的是类本身中没有
FRAME
变量。。所以这一行:
FRAME=new SDL_Rect*[S_total]代码>
将导致编译错误,并且析构函数使用FRAME
,但不存在此类变量。我想你是想把它改成F
,因为如果不是,那么这行:
F[index]=NULL代码>
是未定义的行为,因为F未初始化
此外,您从未初始化帧的每个索引,因此在析构函数中访问它,如:
帧[s][f].x=0代码>
这是一个禁忌
再一次,你打电话
delete[] F;
F = NULL;
但是F没有分配内存,并且未初始化
因此,对于所有补丁,我认为:
class s_group
{
private:
SDL_Surface* image;
unsigned int* F_total;
float* F_length;
SDL_Rect** FRAME;
float* F_current;
unsigned int S_total;
unsigned int S_current;
void Release();
public:
s_group(void);
virtual ~s_group(void);
bool setup(const char* filename, unsigned int s);
//other member functions
};
bool s_group::setup(const char* filename, unsigned int s)
{
Release();//delete already allocated heap memory
if(!load_file(image, filename))
{
image = NULL;
return false;
}
S_total = s;
FRAME = new SDL_Rect*[S_total];
F_total = new unsigned int[S_total];
F_length = new float[S_total];
F_current = new float[S_total];
for(unsigned int index = 0; index < S_total; ++index)
{
FRAME[index] = NULL;
F_total[index] = 0;
F_length[index] = 0.f;
F_current[index] = 0.f;
}
//loop for each array slot and set values of data
return true;
}
void s_group::Release()
{
SDL_FreeSurface(image);
image = NULL;
for(unsigned int s = 0; s < S_total; ++s)
{
for(unsigned int f = 0; f < F_total[s]; ++f)
{
if (FRAME[s])
{
FRAME[s][f].x = 0;
FRAME[s][f].y = 0;
FRAME[s][f].w = 0;
FRAME[s][f].h = 0;
}
}
delete[] FRAME[s];
FRAME[s] = NULL;
}
delete[] FRAME;
FRAME = NULL;
delete[] F_total;
F_total = NULL;
delete[] F_length;
F_length = NULL;
delete[] F_current;
F_current = NULL;
S_total = 0;
S_current = 0;
}
s_group::~s_group(void)
{
Release();
}
类s_组
{
私人:
SDL_表面*图像;
无符号整数*F_总计;
浮动*F_长度;
SDL矩形**帧;
浮动*F_电流;
无符号整数S_总计;
无符号整数S_当前;
无效释放();
公众:
s_集团(无效);
虚~s_群(void);
布尔设置(常量字符*文件名,无符号整数);
//其他成员职能
};
布尔s_组::设置(常量字符*文件名,无符号整数)
{
Release();//删除已分配的堆内存
如果(!加载_文件(图像、文件名))
{
image=NULL;
返回false;
}
S_总数=S;
帧=新SDL_Rect*[S_total];
F_total=新的无符号整数[S_total];
F_长度=新浮点数[S_总数];
F_电流=新浮点数[S_总计];
for(无符号整数索引=0;索引
我应该这样做。。只是别忘了为FRAME[index]
分配内存,我不确定要分配多少或分配什么,所以我更改了Release
函数,以检查FRAME[index]
是否对if语句有效
我强烈建议您使用一些智能指针
,忘记自己处理每个内存分配。发布此问题后,我找到了错误的来源并解决了问题。
在为动态2D数组设置数据值的单独代码部分中,循环验证不正确
for( unsigned int index = 0; index <= F_total[ S_current ]; ++index ) {
//set data values for each slot in the array
F[ S_current ][ index ].x = 0; etc...
}
用于(unsigned int index=0;index永远不要像那样调用您自己的析构函数..我只在分配器中见过这种用法..虽然我不能给您完整的答案,因为我现在无法测试您的代码。我可以告诉您,您永远不应该直接调用析构函数。将代码放在单独的私有方法中可以在setup方法和析构函数。另外,在调用delete之前检查变量是否不为null。现在,如果在不调用“setup”方法的情况下删除对象,代码将崩溃。最后,尽量避免将“initialize”或“setup”分开
for( unsigned int index = 0; index <= F_total[ S_current ]; ++index ) {
//set data values for each slot in the array
F[ S_current ][ index ].x = 0; etc...
}
for( unsigned int index = 0; index < F_total[ S_current ]; ++index ) {
//set data values for each slot in the array
F[ S_current ][ index ].x = 0; etc...
}