2010-12-04 12 views
0

私のコードでは、ポインタ(例:float **変数)へのポインタがいくつかありますが、メモリリークを引き起こさないようにメモリを解放する問題があるようです。ここで私が書いたコードは次のとおりです。Cポインタをポインタに解放する

float *one, **part1, **part2; 

one = malloc(sizeof(&one) * nx * nx); 
part1 = malloc(sizeof(&part1) * nx); 

if(one == NULL || part1 == NULL) { 
printf("Memory error.\n"); 
exit(2); 
} 

for(k = 0; k < nx; k++) 
part1[k] = &one[k * nx]; 

one = malloc(sizeof(&one) * nx * nx); 
part2 = malloc(sizeof(&part2) * nx); 

if(one == NULL || part2 == NULL) { 
printf("Memory error.\n"); 
exit(2); 
} 

for(k = 0; k < nx; k++) 
part2[k] = &one[k * nx]; 

... (Other code here) 

for(k = 0; k < nx; k++) { 
free(part1[k]); 
free(part2[k]); 
} 

free(one); 
free(part1); 
free(part2); 

このコードは、通るの計算を正確に行いますが、その後、自由なループでエラーが出て。 k = 0で動作しますが、part1 [1]とpart2 [1]を解放しようとすると、 "glibc detected"エラーが表示されます。

答えて

2

まず:

one = malloc(sizeof(&one) * nx * nx); 
part1 = malloc(sizeof(&part1) * nx); 

をこれらはあなたがfloat sおよびfloat * Sの束を割り当てたい

one = malloc(sizeof(*one) * nx * nx); 
part1 = malloc(sizeof(*part1) * nx); 

する必要があります、float **sおよびfloat ***s

次に、4つの割り当てを行います。part1,にはoneとインデックスを割り当て、もう一度one(古いアドレスを忘れる)とインデックスをpart2に割り当てます。 part1part2、と指摘するoneメモリの両方の塊:

これは、あなたが4 free()秒を持つことを意味します。最初のoneを上書きするため、そのポインタが失われてしまい、直接free()できません。幸いにも、あなたはpart1[0]にそのポインタを保存し、それを指し示すすべてのメモリfree()に使用することができます。

別の(おそらくもっと慣れている)オプションは、別々に割り当てることです。 part1を割り当ててから、ループしてpart1[k]を割り当て、part2を割り当てます。

+0

メモリが連続していないので、これをやりたくありませんでしたか?私はこれが効率のいくらかの損失を引き起こすと信じています。明らかに、非効率的に作業することはまったく動作しないよりも優れていますが、私はこれをこのように動作させようとしていました。また、ポインタをpart1 [0]以上のものに保存します。私の最初のループは、kが0からnxになるので、part1 [k]にポインタを保存します。そのため、同じ量のメモリを解放しようとしました。 – wolfPack88

+1

"私の最初のループは、kが0からnxになるので、part1 [k]にポインタを保存します。"いいえ、あなたは_offsets_を1つ保存します。 &one [0] = one。 &one [k] = one + k。 free(1)は空き領域のようにメモリ全体を解放します(part1 [0])。 – wnoise

+0

ああ...それは意味をなさない。お手伝いありがとう。 – wolfPack88

1

コールは4つしかありません。したがって、freeコールが4つ必要です。あなたはループで何も割り当てなかったので、なぜあなたはループで解放されていますか?

part1[k]part2[k]

は、彼らはただ oneに割り当てられたメモリの領域を指し、それ自身によって割り当てられたことはありませんので、あなたは oneだけ無料はず。また、あなたはここでメモリリークを持っています。

one = malloc(sizeof(&one) * nx * nx); 
part1 = malloc(sizeof(&part1) * nx); 

... 

// *** You just lost the previous old pointer here *** // 
one = malloc(sizeof(&one) * nx * nx); 
part2 = malloc(sizeof(&part2) * nx); 

すなわちpart1[0]が実際にoneブロックの先頭を指し、part1[0] == &one[0] == oneので、あなたのコードがk = 0のために働く理由がある - これを解放することによって、あなたは全体のブロックを解放しています。

あなたのsizeofの意味はわかりません。私はあなたがnx * nx浮動小数点数を割り当てたいと思っています - もしそうなら、それはsizeof(*one) - *oneは浮動小数ですが、&onefloat **ポインタのoneのアドレスです。あなたがやっているどのように多くのmallocので

one1 = malloc(sizeof(*one) * nx * nx); 
part1 = malloc(sizeof(*part1) * nx); 

... 

for(k = 0; k < nx; k++) 
part1[k] = &one1[k * nx]; 

... 

free(part1); 
free(one1); 
+0

これは私の最初の試みでしたが、それは私にメモリリークを与えていました(つまり、繰り返しループの数時間後、10GBのメモリを占有していました。 – wolfPack88

+1

@ wolfPack88:上記の可能性のあるリークを考えましたか?すなわち、別々の2つの「1つの」ブロックを別々にして、両方を解放しましたか? – casablanca

+0

私はしませんでしたが、メモリリークの原因になるかどうかは確かではありませんでした...私はpart1に1つのポインタを格納し、part1を解放すれば、メモリリークはないはずです。または私はメモリ割り当ての仕組みを誤解していますか? – wolfPack88

1

ルックをし、どのように多くのことは、あなたがやっている解放します:


は、あなたは本当にこのような何かをやっているしたいと思います。数字が一致しません。

一般に、malloc構造の一部を解放することはできません。あなたはそれだけをすべて解放することができます。だから、最後に、あなたがより多くのような何かしたい:すべての

... (Other code here) 
/* four mallocs so four frees */ 
free(part1[0]); 
free(part2[0]); 
free(part1); 
free(part2); 
関連する問題