2016-09-25 16 views
0

私は自分のコードでメモリリークを避けようとしています。 pImage内の値を失うことなく、pElement、lineおよびpSecondの割り当てを解除する必要があります。なぜなら、私はそれらの値を自分のプリント機能の中にプリントする必要があるからです。私は必要な構造体ポインタを解放する方法

私の追加機能には、GraphicElement * pElement、struct GraphicElement * pSecond、struct Point pointが含まれています。

私は構造体ごとにmallocを使ってメモリを割り当てた後、値を追加してから最終値をpImageに渡します。すべての私の他の関数は、私が常に3つのメモリリークで終わるという事実に加えて完全に機能します。私は無料ではなかったので(p秒); ....無料(pElement)...無料(行);

関数を終了してから値をpImageに渡す前に解放しようとするとします。私の値はすべて消去されます。

追加機能内でこれらの値をローカルで解放するにはどうすればよいですか?私はローカルに自分のadd関数の内部でこれらの値を解放することができますどのように

struct Point 
{ 
    int x, y; 
}; 

struct Line 
{ 
    Point start; 
    Point end; 
}; 

struct GraphicElement 
{ 
    enum{ SIZE = 256 }; 
    unsigned int numLines; //number of lines 
    Line* pLines; //plines points to start and end 
    char name[SIZE]; 
}; 

typedef struct 
{ 
    unsigned int numGraphicElements; 
    GraphicElement* pElements; //the head points to pLines 
} VectorGraphic; 

void InitVectorGraphic(VectorGraphic*); //initializes pImage->pElement 
void AddGraphicElement(VectorGraphic*); //Used to add 
void ReportVectorGraphic(VectorGraphic*); // prints pImage contents 
void CleanUpVectorGraphic(VectorGraphic*); //deallocates memory 
+1

あなたpImageは、それらの値を使用しているように聞こえます。なぜ彼らはあなたの追加で解放される必要がありますか?あなたの 'CleanUpVectorGraphic'関数でそれらを解放してみませんか? – NullEntity

+1

structポインタが必要な場合は、なぜそれを最初から解放したいのですか? IMO、私はあなたが達成しようとしていることを理解していないので、あなたがしたいことを説明する必要があります。 –

+1

@Disillusioned私は別の関数からそれらの構造体にアクセスできますか?私は自由にできることを知っている(pImage)。その内容はすべてループ内にあります。しかし、line、pSecond、pElementはどうでしょうか?クリーンアップ機能からどのようにアクセスするのですか? – Calidreaminn

答えて

1

ローカルに割り当てられたメモリを明示的に解放することはできません。また、は無料です。いくつかのメモリはありません。解放されると、メモリスロットにアクセスすることはできず、内部に格納されたデータは失われます。

Cでは、メモリを割り当てるオプションが2つあります。ヒープまたはスタックに割り当てることができます。ヒープ上に予約されているメモリスロットはグローバルにアクセスでき、明示的に解放されるまで残ります。スタックに予約されているものは、作成されたコンテキスト内にとどまっている間のみ有効です。

のは、あなたが次のコードを実行しましょう:

void func() 
{ 
    int x = 3; // [2] 
    int * p = & x; // [3] 
} 

int main() 
{ 
    func();   // [1] 

    // [4] 
    return 0; 
} 

命令[2]がスタック上にいくつかのメモリを割り当てます。 2番目のもの([3])は同じことを行い、最初の変数のアドレスを新しいメモリスロットに格納します。関数が([4])を返した後、このメモリは解放されます。グラフィカルに、ここで何が起こるかです:

 Context STACK Address 
       +---------+  
       |   | 0xa1 
     main |   | 0xa0    
       +---------+  

[1]   +---------+ 
=====>  |   |   
     func |   | 0xa2   
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[2]   +---------+ 
=====>  |   | 
     func | 3  | 0xa2 <-- x 
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[3]   +---------+ 
=====>  | 0xa2 | 0xa3 <-- p 
     func | 3  | 0xa2 <-- x 
       +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[4]   +---------+ 
=====>  |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

だから私は、関数の内部でmalloc関数を使用している場合。関数が存在すると、ヒープ上の割り当てられたメモリは自動的に解放されますか?

これは逆です。 mallocのような関数を使用すると、メモリスロットがヒープに割り当てられます。我々は

int * p = malloc(sizeof(int)); // [3] 

のようなものに上記の行に[3]を変更するのであれば、あなたが機能を残しておきますと、スタックに割り当てられたメモリが解放されますが、ヒープ上に割り当てられたメモリが割り当てられたままになり、今でもアクセスできるようになりますあなたがそれを解放するまで。グラフィカル:あなたが見ることができるようにあなたが機能を離れた後

            HEAP  Address Free (y/n) 
               +---------+ 
               |   | 0xb4 - Yes 
               |   | 0xb3 - Yes 
               +---------+ 
     Context STACK Address    
[3]   +---------+      +---------+ 
=====>  | 0xb4 | 0xa3 <-- p   |   | 0xb4 - No 
     func | 3  | 0xa2 <-- x   |   | 0xb3 - Yes 
       +---------+      +---------+ 
       |   | 0xa1 
     main |   | 0xa0 
       +---------+ 

[4]   +---------+      +---------+ 
=====>  |   | 0xa1     |   | 0xb4 - No !!! Leak !!! 
     main |   | 0xa0     |   | 0xb3 - Yes 
       +---------+      +---------+ 

、あなたが動的に割り当てられたメモリへのポインタを持っていないとメモリリークを持っています。これを回避する1つの方法は、ポインタを返すことです(新しいメモリスロットのアドレスを呼び出し関数に渡す)か、後で解放するためにどこかに格納します。関数を呼び出す前にメモリを割り当てて、それを関数としてパラメータとして渡すこともできます。それは本当にあなたのアプリケーションに依存します。

関連する問題