2008-09-19 108 views
6

我在生成int矩陣時沒有產生內存泄漏問題。我希望能夠通過read_matrix()動態地將給定(全局)矩陣變成任意大小。但之後我希望能夠在以後釋放內存。所以在我的主要方法中,第二個printf應該會導致總線錯誤,因爲它不應該分配任何內存。我將如何去創造這個?int指針在C中的矩陣 - 內存分配混淆

int**  first_matrix; 
int**  second_matrix; 
int**  result_matrix; 

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, sizeof(int*)); 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

int main(int stackc, char** stack) 
{ 
    first_matrix = read_matrix(10,10); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
    free(*first_matrix); 
    free(first_matrix); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
} 

回答

9

只是因爲內存已經free'd並不意味着你無法訪問它!當然,這是一個非常糟糕的想法,它可以在free'd後訪問它,但這就是爲什麼它在你的例子中有效。

請注意,free(*first_matrix)只有免費的first_matrix[0],而不是其他陣列。您可能需要某種標記來表示最後一個數組(除非您始終知道何時釋放外部數組可以分配多少個內部數組)。喜歡的東西:

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    matrix[size_x] = NULL; // set the extra ptr to NULL 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

然後當你釋放他們:

// keep looping until you find the NULL one 
for(int i=0; first_matrix[i] != NULL; i++) { 
    free(first_matrix[i]); 
} 
free(first_matrix); 
2

您需要單獨釋放每一行:


void free_matrix(int **matrix, int size_x) 
{ 
    for(int i = 0; i < size_x; i++) 
     free(matrix[i]); 
    free(matrix); 
} 
+0

您不能在C中的for循環中聲明變量。 – terminus 2008-09-19 21:26:56

+2

您可以在C99中使用,但是您的代碼不能反向移植。 – 2008-09-19 21:59:20

0

你只釋放first_matrix的第一行(或列)。寫另一個像這樣的函數:

void free_matrix(int **matrix, int rows) 
{ 
    int i; 
    for(i=0; i<rows; i++) 
    { 
     free(matrix[i]); 
    } 
    free(matrix); 
} 

您可能希望將矩陣變成一個結構來存儲它的行數和列數。

1

釋放內存不會使它消失,這只是意味着另一個分配可能會佔用同一塊內存。無論你放在哪裏,它都會一直存在,直到其他東西被覆蓋。

此外,你沒有釋放你分配的所有東西。你只是釋放指針數組和第一行。但即使你正確地釋放了一切,你仍然會有同樣的效果。

如果你想創建一個「總線錯誤」,你需要指向不屬於你的進程的內存。無論如何,你爲什麼要這麼做?

+0

我只是想做到這一點,以表明內存是免費的,但現在知道錯誤在我的思維中,不能運行valgrind,因爲我在OS X上,想要一種方式來看看我是否真的已經釋放它 – Fredrik 2008-09-19 21:33:28

0

我推薦使用valgrind來追蹤自由內存,而不是試圖發生總線錯誤。它也有許多其他的東西。

山姆

+0

我在OS X上,所以我不能運行valgrind,否則我會:/ 你知道任何可以在mac上使用的替代方法嗎? – Fredrik 2008-09-19 21:34:20

0

你得到的內存泄漏,因爲你釋放矩陣的第一行和列的清單,但沒有1到第n行。您需要在循環中免費撥打電話。

有幾個選擇,但是: - 分配的sizeof(INT *)行+行的cols *的sizeof(int)的字節,並使用第一個字節的行指針。這樣,你只有一塊內存空閒(並且在分配器上也更容易) - 使用包含行數的結構。然後你可以完全避免行列表(保存內存)。唯一的缺點是你必須使用一個函數,一個宏或者一些雜亂的符號來解決矩陣問題。如果你使用第二個選項,你可以在任何C99編譯器中使用這樣的結構,並且只需要分配一個內存塊(大小爲numints * sizeof(int)+ sizeof(int)) :

struct matrix { 
    int rows; 
    int data[0]; 
} 
0

你錯過這裏的概念,是一個爲每個釋放calloc,必須有一個免費的。 並且自由必須應用於從calloc傳回的指針。

我建議你創建一個函數(名爲delete_matrix) 使用一個循環來釋放所有您在這裏

爲分配指針(INT I = 0;我< size_x;我++){ matrix [i] = calloc(size_y,sizeof(int)); }

然後,一旦完成,釋放由此分配的指針。

matrix = calloc(size_x,sizeof(int *));

你現在正在做的方式,

免費(* first_matrix); free(first_matrix);

不會做你想做的事情。