2015-10-17 43 views
0

當我喜歡運行代碼如下:解放出來動態2D陣列未按預期用C

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

int main (void) 
{ 
    int i, count = 0x09; 
    int sizei = 5, sizej = 2; 

    int **ary = malloc (sizei * sizeof **ary); 
    for (i = 0; i < sizei; i++) { 
     *(ary + i) = malloc (sizej * sizeof *(ary + i)); 
     **(ary + i) = ++count; 
     printf (" %2d |%p| +%x+ \n", i, (ary + i), *(*(ary + i))); 
    } 

    puts("----"); 
    for (i = sizei - 1; i >= 0; i--) { 
     printf (" %2d |%p| +%x+ \n", i, (ary + i), *(*(ary + i))); 
     free (*(ary + i)); 
    } 
    puts("----"); 

    free (ary); 
    return 0; 
} 

我期望的是,第一半將產生整數稱爲ary的2D動態陣列(即一個指針一個動態分配的指針數組,每個指向一個動態分配的ints數組)。每個陣列**(ary + i)的第0個元素將被遞歸地分配的count當前值。

下半部分將反向迭代,釋放每個元素ary,反過來它是malloc'd,然後釋放ary本身。

這似乎做工精細,直到我嘗試釋放*(ary + 0),在這一點上,我得到一個雙免費/損壞錯誤。我已經包含了輸出。

0 |0x1d6f010| +a+ 
    1 |0x1d6f018| +b+ 
    2 |0x1d6f020| +c+ 
    3 |0x1d6f028| +d+ 
    4 |0x1d6f030| +e+ 
---- 
    4 |0x1d6f030| +e+ 
    3 |0x1d6f028| +d+ 
    2 |0x1d6f020| +c+ 
    1 |0x1d6f018| +b+ 
    0 |0x1d6f010| +1d6f0b0+ 
*** Error in `./a.out': double free or corruption (out): 0x0000000001d6f030 *** 

我很好奇爲什麼ary第0個元素的0號元素(即*(*(ary + 0) + 0))或只是**ary)成爲什麼樣子一些內存地址(僅適用於性能稍微)出從什麼就由這個二維數組邊界一旦它退出第一個循環。

如果我擺脫了第二循環的,只是嘗試直接免費ary沒有首先釋放的任何元素,我得到的是這樣的:

0 |0x1d6f010| +a+ 
    1 |0x1d6f018| +b+ 
    2 |0x1d6f020| +c+ 
    3 |0x1d6f028| +d+ 
    4 |0x1d6f030| +e+ 
---- 
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000001d6f010 *** 

我不明白我做了什麼錯這裏。使用數組符號會有所作爲嗎?我需要的任何解決方案,讓我有如果在所有可能的的ary其餘元件的長度的每個陣列獨立的的動態長度。的ary的數量的元件將不necesarily在編譯時是已知的。如果這是相關的,我使用gcc 4.9。

回答

2

問題1

int **ary = malloc (sizei * sizeof **ary); 

相當於

int **ary = malloc (sizei * sizeof int); 

如果sizeof指針低於sizeof(int)在你的系統,你最終訪問內存越界。

您需要使用:

int **ary = malloc (sizei * sizeof *ary); 

int **ary = malloc (sizei * sizeof(int*)); 

問題2

*(ary + i) = malloc (sizej * sizeof *(ary + i)); 

需求是

*(ary + i) = malloc (sizej * sizeof **(ary + i)); 

*(ary + i) = malloc (sizej * sizeof int); 

ary[i] = malloc (sizej * sizeof *ary[i]); 

ary[i] = malloc (sizej * sizeof int); 
0

ari是指針到指針的數組,所以元件的大小是指針。在代碼中,使用sizeof **ary其爲int

int **ary = malloc (sizei * sizeof **ary); 

對於每個指針int元件的陣列組成。在你的malloc對這些指針,你用sizeof *(ary+i)這是一個指向int

 *(ary + i) = malloc (sizej * sizeof *(ary + i)); 

的sizeof(int)的並不總是一樣的sizeof(INT *)。事實上,在大多數64位的系統上,我懷疑你使用的是sizeof(int)== 4和sizeof(int *)== 8。我的猜測是你正在使用這樣一個系統,因此,你不會爲主ari指針分配足夠的內存,並且你正在使用值溢出它,抖動關鍵內存管理數據的內容,以便將來的malloc ()和free()調用很有可能完全失敗。