2014-01-17 111 views
1

考慮下面的代碼寫在C:免費指針從堆棧結構C

#include<stdio.h> 
#include<stdlib.h> 

typedef struct { 
    int var; 
    int **m; 
} STRUCTURE; 

int main() { 
    STRUCTURE a; 
    int i, j; 

    a.var = 5; 

    a.m = malloc(a.var * sizeof(int *)); 
    for(i = 0; i < a.var; i++) { 
     a.m[i] = calloc(a.var, sizeof(int)); 
    } 

    for(i = 0; i < a.var; i++) { 
     a.m[i][i] = 1; 
    } 

    for(i = 0; i < a.var; i++) { 
     for(j = 0; j < a.var; j++) { 
      printf("%d ", a.m[i][j]); 
     } 
     printf("\n"); 
    } 

    return 0; 
} 

這會簡單輸出:

1 0 0 0 0 
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 0 
0 0 0 0 1 

鑑於該結構在主宣佈,但指針的事實它是動態分配的,它們應該如何釋放?如果他們應該。

謝謝!

+1

他們應該使用'free' ...提示:它與'malloc'如何使用它們相似。 – Kninnug

回答

5

任何你malloc版必須free d以及。退出時是一個例外,因爲操作系統通常會聲明內存(取決於操作系統)。儘管它在技術上不會是內存泄漏,但它仍然被認爲是不好的做法。

免費應該按照您用來分配的順序進行。

for(i = 0; i < a.var; i++) { 
    free(a.m[i]); 
free(a.m); 

原因是,在釋放主體之前,您無法釋放主體,因爲它們無法再訪問。

+0

如果我在'main'中聲明我的結構,並將它的地址發送到一個'void function(STRUCTURE * a)'中,並且我在該函數中分配了我的矩陣,該怎麼辦?我可以按照'main'說的方式釋放我的矩陣嗎?還是必須從函數中釋放它? –

+1

你可以把它放在任何你喜歡的地方。但是,你應該注意範圍。如果你將一個指針傳遞給一個可以釋放它的函數,調用者仍然有指針,但它當然不再有效。雖然有一個限制,您可以使用相同的方法來釋放內存,就像您用來分配內存一樣。所以如果你混合使用C和C++代碼,你不應該使用'new'和後來的'free',而應該使用'delete',當然這同樣適用於其他方式。 – Devolus

+0

非常感謝您提供一個很好的答案! :) –

1

在反向

for(i = 0; i < a.var; i++) { 
    free(a.m[i]); 
} 
free(a.m); 
+0

非常感謝您的回答! :) –

4

free()malloc的工作方式相同,但您通常需要的順序相反。你應該使用類似這樣的東西:

for(i = 0; i < a.var; i++) { 
    free (a.m[i]); 
} 
free (a.m); 
+0

從來不知道。你有參考嗎? – Jori

+2

我不認爲你需要一個參考!指向堆分配對象的指針放在'a.m [i]'中,這就是'free()'所需要的。很明顯,你需要'free(a.m)'後,否則你會解除引用釋放內存,當你釋放(a。m [i])' – abligh

+0

非常感謝您的回答! :) –