我的程序是使用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;
}
在一個大的功能我在堆上創建這個類的一個對象,存儲其地址在名爲sparkle
的s_group
指針。
s_group* sparkle = new s_group;
sparkle->setup("sparkle_final.png", 1);
在功能上完成我叫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;
}
在到達delete運算符,會出現一個對話框,指出:
Windows已經引發了Program.exe文件斷點。這可能是由於堆的損壞,這表明Program.exe或它已加載的任何DLL中存在一個錯誤。
我該如何delete
這個對象不會導致堆損壞?
永遠不要調用你自己的析構函數那樣..我只見過這用於分配器.. – Brandon
儘管我不能給你一個完整的答案,因爲我現在無法測試你的代碼。我現在可以告訴你,你永遠不應該直接調用析構函數。把代碼放在一個單獨的私有方法中可以在設置方法和析構函數中調用它。另外,在調用delete之前檢查一個變量是否爲空。現在,如果您在不調用「setup」方法的情況下刪除對象,則代碼將崩潰。最後,儘量避免單獨的「初始化」或「設置」方法,使用構造函數來初始化類。 –
'我如何刪除這個對象而不會導致堆損壞? '如果您使用C++容器和/或智能指針,那麼堆損壞將大大減少,或者完全消除。在C++的這個時代,用戶類不需要像你所做的那樣編碼。 – PaulMcKenzie