[英]How to delete a dynamic array of structs (C++)?
我正在建立一個分配動態結構數組的類,該結構數組包含另一個結構。 問題是結構中的所有元素都是固定大小的,所以釋放內存的常規方式就足夠了(刪除[]數組)嗎?
struct TRANSITION
{
int transition;
int next_state;
};
struct state
{
int transitionCount = 0;
string stateName;
string stateAction;
TRANSITION transitions[50];
};
類的構造函數/析構函數:
FSM(int n)
{
numberOfStates = n;
states = new state[numberOfStates];
currentState = 0; //First state numbered state 0
stateCount = 0;
}
~FSM() { delete[]states; };
這是刪除此數組的正確方法嗎?
簡短說明:是的,考慮到上面的代碼,這是正確的方法。
詳細描述:
假設變量states
是state*
,則問題可以分為兩部分:
由於沒有為該結構定義顯式析構函數,並且該結構正在new[]
定義中使用,因此編譯器將為該結構創建默認的隱式析構函數(請參見: ISO C ++標准工作草案 ,第287頁)。 該析構函數調用該結構中包含的所有元素的析構函數,因此可以逐一刪除數組中的元素。
還有一個隱式運算符delete[]
,它調用所有數組元素的各個析構函數,以確保正確的級聯。 (參考: C ++參考 )
總體而言,該組合允許使用delete[]
結構數組。
是的,對於每個new
都有一個delete
。 考慮到我們正在處理固定大小的數組, delete[]
正是所需要的。
根據RAII原則,在構造函數中具有new
並在析構函數中具有delete
也很好。
另一種驗證方法是檢查程序中的內存泄漏。 例如,在Visual Studio中,以下內容不顯示內存泄漏:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
#include <string>
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
struct TRANSITION {
int transition;
int next_state;
};
struct state {
int transitionCount = 0;
std::string stateName;
std::string stateAction;
TRANSITION transitions[50];
};
class FSM {
public:
FSM(int n);
~FSM();
int numberOfStates;
state* states;
int currentState;
int stateCount;
};
FSM::FSM(int n)
{
numberOfStates = n;
states = new state[numberOfStates];
currentState = 0; //First state numbered state 0
stateCount = 0;
}
FSM::~FSM() { delete[] states; };
//FSM::~FSM() { };
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
FSM fsm(3);
return 0;
}
但是,如果刪除delete[] states;
語句然后產生:
Detected memory leaks!
Dumping objects ->
{160} normal block at 0x0000024535F03B00, 16 bytes long.
Data: < V 5E > D8 56 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
{159} normal block at 0x0000024535F04730, 16 bytes long.
Data: < V 5E > B0 56 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
{158} normal block at 0x0000024535F03A10, 16 bytes long.
Data: < T 5E > F0 54 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
{157} normal block at 0x0000024535F03AB0, 16 bytes long.
Data: < T 5E > C8 54 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
{156} normal block at 0x0000024535F03DD0, 16 bytes long.
Data: < S 5E > 08 53 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
{155} normal block at 0x0000024535F046E0, 16 bytes long.
Data: < R 5E > E0 52 F0 35 45 02 00 00 00 00 00 00 00 00 00 00
c:\users\username\documents\visual studio 2015\projects\project60\project60\main.cpp(41) : {154} normal block at 0x0000024535F052D0, 1472 bytes long.
Data: < > 03 00 00 00 00 00 00 00 00 00 00 00 CD CD CD CD
Object dump complete.
跟蹤所有new
和delete
語句可能很棘手,因此最好的方法通常是使用標准庫容器之一,例如原型std::vector
。
另一種可能更輕松的修改可能是使用諸如std::unique_ptr
類的智能指針:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <iostream>
#include <string>
#include <memory>
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif // _DEBUG
struct TRANSITION {
int transition;
int next_state;
};
struct state {
int transitionCount = 0;
std::string stateName;
std::string stateAction;
TRANSITION transitions[50];
};
class FSM {
public:
FSM(int n);
~FSM();
int numberOfStates;
//state* states;
std::unique_ptr<state[]> states;
int currentState;
int stateCount;
};
FSM::FSM(int n)
{
numberOfStates = n;
//states = new state[numberOfStates];
states = std::make_unique<state[]>(numberOfStates);
currentState = 0; //First state numbered state 0
stateCount = 0;
}
//FSM::~FSM() { delete[] states; };
FSM::~FSM() { };
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
FSM fsm(3);
return 0;
}
沒有忘記delete
風險,我們也可能會感到有些安全,也看不到任何new
語句。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.