Cメモリリーク問題の検討


メモリリーク
不注意やエラーにより、プログラムが使用されなくなったメモリを解放できなかった場合を指します.メモリ漏洩とは、内部に物理的に消失することではなく、アプリケーションがメモリを割り当てた後、設計エラーにより、メモリを解放する前にメモリの制御が失われ、メモリの無駄になります.
メモリの漏洩の原因は、次のような場合が多いです.
1.初期化されていないメモリ
char *p = malloc ( 10 );

  pには10バイトが割り当てられています.この10バイトは、ごみデータを含むコードセグメントがアクセスしようとすると、ごみ値が取得される可能性があります.
プログラムには予測不可能な動作がある可能性があります.pは、プログラムが予想外の値を持っている可能性があります.
良い実践は、memsetおよびmallocを常に組み合わせて使用するか、またはcallocを使用することである. 
char *p = malloc (10);
memset(p,’\0’,10);

これにより、同じコードセグメントがpに値を付与する前にアクセスしようとしても、このコードセグメントはNull値(理想的には持つべき値)を正しく処理し、その後、正しい動作を有することができる.
 
2.メモリオーバーライド
3.リードアウト
メモリ読み出しオーバーラップ(overread)とは、読み出したバイト数がそれらのバイト数より多いことを意味する.
 
4.動的購買依頼を即時に解放していないヒープメモリ
#include <stdlib.h>
#include <iostream>
using namespace std;
 
void GetMemory(char *p, int num)
{
    p = (char*)malloc(sizeof(char) * num);//  new       
} 

int main(int argc,char** argv)
{
    char *str = NULL;
    GetMemory(str, 100);
    cout<<"Memory leak test!"<<endl;
    //  main   while    GetMemory
    //          
    //while(1){GetMemory(...);}
    return 0;
}

良い実践をまとめると、
常にmemsetとmallocを組み合わせて使用するか、callocを常に使用します.
ポインタに値を書き込むたびに、使用可能なバイト数と書き込まれたバイト数が交差していることを確認します.
ポインタに値を割り当てる前に、メモリの場所が孤立していることを確認します.
構造化された要素(動的に割り当てられたメモリの位置を指すポインタも含む)を解放するたびに、サブメモリの位置を最初に巡り、そこから解放してから親ノードに戻ります.
動的に割り当てられたメモリ参照を返す関数の戻り値を常に正しく処理します.
各mallocには対応するfreeが必要です.
空のポインタにアクセスしていないことを確認します.