C++ 删除堆上存储数据的对象

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;

我的程序是使用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;

    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...
}