2016-04-29 11 views
-2

新しいキーワードを繰り返し使用すると、私はメモリリークに非常に注意しています。次の例では、メモリリークがありますか?私の腸の本能ははいと言います。この状況でメモリリークが発生しましたか?

class Handler  // Class definition 
{public: 
    ~Handler(); 
    int* ptrToInts;  
}; 

Handler::~Handler() // Class destructor 
{ 
    delete[] ptrToInts; 
} 

Handler handler;  // Global object 


void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 


int main() 
{ 
    bool quit = false; 

    while(!quit) 
    { 
     aFunction(); 
    } 

    return 0; 
} 

ptrToIntsは、heapeach時間に別々のメモリに20個の別々の新しいintを作成するでしょうか?

また、デストラクタ用でない場合、動的に割り当てられたメモリを解放するかどうかが問題です。クラスの生存期間はプログラムの継続時間であるかのように見て、すべての「新しい」メモリーのクリーンアップを行いますか?

編集:ありがとうございました。私がこれを求めている理由は、WndProcが基本的にRaw Inputのために呼び出されるたびに、新しい呼び出しと削除を呼び出そうとしているからです。これはMSDNがあなたに指示する方法です。非常に非効率だと思われる。

+1

なぜこのようHandlerクラスを実装していません。彼らはバランスを取る必要があります。 –

+0

あなたのプログラムにメモリリークがあるかどうか(そしてどこで)どこにあるのかを教えてくれるツール(http://valgrind.org/など)を使用してください。 – simpel01

+0

valgrindはMS Windowsプラットフォームでは動作しません。 – cwschmidt

答えて

6

、あなたはメモリを作成リーク。これは、ポインタが呼び出されるたびにポインタを再割り当てするため、aFunction()をループすると発生します。

2番目の質問では、デストラクタはポインタに割り当てられた最後の配列delete[]だけです。

+0

このコードを実行するとどうなりますか?私は自分のコンピュータでそれを実行するつもりはないが、私はオンラインのものを試してみたが、bad_allocを投げた後に停止した。 – Zebrafish

+0

@TitoneMaurice:それはまさに自分のコンピュータで起こることだろう。それは完全に無害です。プログラムがクラッシュし、OSがメモリを再利用します。 –

+0

@TitoneMaurice、あなたのプロセスのためにシステムは数秒以内にメモリ不足になります....そして、これは速く失敗したことは非常に良いことです!あなたはソフトウェアの遅れを望んでいません。 – WhiZTiM

2

delete[]は、newによって割り当てられたメモリを解放します。 newを使用するたびに、にはdeleteが必要です。 Documentationに基づいて他の質問については、

:とすぐに、ヒープ上の割り当て解除その割り当てられたメモリにdelete[]を使用せずにポインタを再割り当てとして

MyClass * p1 = new MyClass[5]; // allocates and constructs five objects

2

はい、呼び出すたびにhandler.ptrToIntsを明示的に割り当て解除せずに、関数を複数回呼び出すとメモリリークが発生します。

void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 

//-----somewhere we see the caller 

while(!quit) 
    { 
     aFunction(); 
    } 

しかし、これはリークを検出する些細なケースです...あなたはLeak detectorsstatic analyzersを使用することを学ぶ必要があります。

は、メモリリークがあるもちろんHow do you detect/avoid Memory leaks in your (Unmanaged) code?

+0

ありがとうございました、ここにいる人がvalgrind.orgにリーク検出を指摘しました。 – Zebrafish

+0

あなたの 'main()'に無限ループがあるので、あなたのケースではvalgrindは動作しません。 – cwschmidt

+0

@cwschmidt、スタティックアナライザが動作します。 - 無限ループを検出する。 :-) ...追加するだけで、両方とも失敗した場合、デバッガは以下を渡すべきです: – WhiZTiM

1

を参照してください。あなたはどうなる

void aFunction() 
{ 
    delete [] handler.ptrToInts; 
    handler.ptrToInts = new int[20]; 
} 

のように、最初の古いint型の割り当てを解除せずに

void aFunction() 
{ 
    handler.ptrToInts = new int[20]; 
} 

にint型を割り当てます。

aFunction()を呼び出すと、「無限の」メモリ割り当てが行われます。 最後に割り当てられたintだけを解放するデストラクタも呼び出されません。

あなたのハンドラがそれ自身のメモリを管理しないのはなぜですか?

オブジェクトの外部にメモリを割り当てて、その内部でメモリを解放することは非常に悪いことです。あなたは `回以上new`と` [] `一度だけ[はい、あなたがメモリリークを持って削除しない場合は

class Handler 
{ 
public: 
    Handler(); 
    ~Handler(); 
    void aMethod(); 
private: 
    int* ptrToInts;  
}; 

Handler::Handler() { 
    handler.ptrToInts = new int[20]; 
} 

Handler::~Handler() { 
    delete[] ptrToInts; 
} 

void Handler::aMethod() { 
    delete[] ptrToInts; 
    handler.ptrToInts = new int[20]; 
} 

int main() { 
    bool quit = false; 
    Handler handler; 

    while(!quit) { 
    handler.aMethod(); 
    } 
} 
関連する問題