2016-03-27 15 views
-1

私は構造体の動的配列を割り当てるクラスを構築しており、構造体の配列には別の構造体が含まれています。 構造体のすべての要素は固定サイズですので、従来のメモリ解放方法で十分です(delete []配列)?構造体の動的配列を削除するには(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; }; 

これは、この配列を削除する正しい方法は何ですか?

+2

どのようなタイプが 'states'ですか?そしてなぜ単に 'std :: vector'や他の何かを使ってあなたのためにしないのですか? –

+0

ここでは「静的」とは見えません。 –

+0

"構造体のすべての要素は静的です"(1)このコードには静的メンバーはありません(2) 'std :: vector'を使用してください。 –

答えて

0

はい、それぞれnewにはdeleteがあります。固定サイズの配列を扱っているので、delete[]は正確に必要なものです。

また、RAIIの原則に従って、コンストラクタにnew、デストラクタにdeleteを持たせるとよいでしょう。

検証するもう1つの方法は、プログラムのメモリリークをチェックすることです。例えば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. 

すべてのnewdeleteを追跡するために注意が必要ですなぜなら、最良の方法は通常、プロトタイプstd::vectorのような標準ライブラリコンテナの1つを使用することです。

#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文を見ていない、より安全を感じることができます。

もう一つ、おそらく軽い、修正は、std::unique_ptrとしてスマートポインタを使用することができます。

1
  1. メンバーは静的ではありません。
  2. それはかなり正しい配列を削除する方法です。
1

短い説明:はい、上記のコードを考慮すると、正しい方法です。

ロング説明:配列の要素のそれぞれの

  1. 破壊、
  2. 破壊:
    変数statesstate*であると仮定すると、問題は二つの部分に分けることができます配列自体の

structには明示的なデストラクタが定義されていないため、struct iコンパイラ(参照:ISO C++ standard working draft、page 287)によって構造体のデフォルトの暗黙的なデストラクタが作成されます。このデストラクタは、構造体に含まれるすべての要素のデストラクタを呼び出すため、配列の要素を1つずつ削除することができます。

暗黙の演算子delete[]は、すべての配列要素の個々のデストラクタを呼び出して適切なカスケードを保証します。 (Ref:C++ Reference

全体では、delete[]を使用して構造体の配列を削除できます。

関連する問題