2014-02-19 100 views
0

我在free()運行這個程序時遇到堆崩潰,但是如果我使用F10(在Visual Studio 2010中)進行調試,我就成功了。二維數組的連續內存分配---釋放內存

我的驗證碼:

以下代碼是用來免費的。有人可以解釋在這種情況下二維數組的解除分配嗎?

void Deallocate2D (SINT32 **pAccess, UINT8 i_ubyNoOfRows) 
{ 
    int i; 
    UINT8 *elem; 
    if (NULL == pAccess) 
    { 
     printf ("%d>Invalid Params\n", __LINE__); 
     return; 
    } 

    printf ("\nDeallocate 2D Array..................\n"); 

    /* Include the code to deallocate the 2D array */ 
    { 
      free(pAccess); 

    } 
} 

在下面的代碼是用於存儲器分配:

的代碼來填充陣列和打印數組:

SINT32 Fill2D ( 
       SINT32 **pnAccess, 
       SINT32 *pnData, 
       UINT8 i_ubyNoOfRows, 
       UINT8 i_ubyNoOfCols) 
{ 
    SINT16 wRIndex, wCIndex, wDataIndex = 0; 



    printf ("\nFill 2D Array..................\n"); 

    /* Include the code to fill the 2D array with the 1D values */ 
    { 
     for(wRIndex = 0 ; wRIndex < 3; ++wRIndex) 
      for(wCIndex = 0; wCIndex < 3; ++wCIndex) 
       pnAccess [wRIndex][wCIndex] = pnData[wDataIndex++]; 

    } 

    if ((NULL == pnAccess) \ 
      || (NULL == pnData)) 
    { 
     printf ("%d>Invalid Params\n", __LINE__); 
     return -1; 
    } 

    return 0; 
} 

SINT32 Print2D ( 
       SINT32 **pnAccess, 
       UINT8 i_ubyNoOfRows, 
       UINT8 i_ubyNoOfCols) 
{ 
    SINT16 wRIndex, wCIndex; 

    if (NULL == pnAccess) 
    { 
     printf ("%d>Invalid Params\n", __LINE__); 
     return -1; 
    } 

    printf ("\n2D Array..................\n\n"); 

    /* Include the code to Print the 2D array in matrix format */ 
    { 
     for(wRIndex = 0 ; wRIndex < i_ubyNoOfRows; ++wRIndex) 
     { 
      if(wRIndex % 2 == 0) 
       printf("\n"); 
      for(wCIndex = 0; wCIndex < i_ubyNoOfCols; ++wCIndex) 
       printf("%d ", pnAccess[wRIndex][wCIndex]); 

     } 
    } 

    return 0; 
} 

在下面的代碼是一種入口點:

void Test2DArray (void) 
{ 
    SINT32 **pnData = NULL; 
    SINT32 nData1[] = { 10, 15, 20, 15, 20, 25, 10, 25, 20 }; 
    SINT32 nData2[] = { 70, 75, 80, 65, 90, 25, 30, 35, 80 }; 

    printf ("\n==================================\n"); 
    printf ("Test 2D Array..................\n"); 
    printf ("==================================\n\n"); 

    if (Allocate2D(&pnData, 3, 3) != -1) 
    { 
     if (Fill2D(pnData, nData1, 3, 3) != - 1) 
     { 
      if (NULL != pnData) 
      { 
       Print2D (pnData, 3, 3); 
       Deallocate2D (pnData, 3); 
      } 
     } 
    } 

    if (Allocate2D(&pnData, 3, 3) != -1) 
    { 
     if (Fill2D(pnData, nData2, 3, 3) != - 1) 
     { 
      if (NULL != pnData) 
      { 
       Print2D (pnData, 3, 3); 
       Deallocate2D (pnData, 3); 
      } 
     } 
    } 
} 
+2

請不要投用'malloc'返回的指針,和經驗法則很簡單:每個'malloc'調用必須與'free'調用配對。 2D數組一次不能釋放,但必須分開釋放每個指針:'char ** foo; for(int i = 0; i

+0

@EliasVanOotegem你假定他正在使用兼容的C編譯器來編譯C代碼。 – Lundin

+0

@lundin:沒有visual-C或C++標籤。如果OP使用VC++編譯器,他應該提及 –

回答

3
/*Contiguous memallocation pAc*/ 
    pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows); 
    if(pAc) 
     pubyPositioner = (UINT8*)malloc(sizeof(UINT8) * i_ubyNoOfCols); 
    if(pubyPositioner) 
     for(i = 0; i < i_ubyNoOfCols; ++i) 
      pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols); 

這不是連續的內存分配!它是一個基於指針的查找表,它被分配在一個段中,指向另一段中分配的一塊內存。分配一個真正的二維數組將

正確的代碼:

SINT32 (*pAc)[ubyNoOfCols] = malloc(sizeof(SINT32[i_ubyNoOfCols][i_ubyNoOfRows])); 
... 
free(pAc); 

注意,這隻會編譯一個C編譯器,所以你不能使用Visual Studio。


能有人請解釋爲釋放在這種情況下,二維數組?

free(pAccess); 

貌似代碼只解除分配指針查找表,而不是實際數據。所以我想這是一個錯誤:代碼包含內存泄漏。

+0

@WhozCraig糟糕,確實有一些複製/粘貼錯誤。感謝您指出,修復。原始代碼中的'pAc'被聲明爲指向指針的指針,這與指向數組的指針不同。是否使用列或行作爲第一維取決於應用程序的性質,不知道它是基於「(x,y)」數學座標還是其他。 – Lundin

+0

不過,這裏的核心問題是:內存沒有相鄰分配,並且在釋放時似乎存在內存泄漏。 – Lundin

+0

thx用於更新。 +1 – WhozCraig

0

讓我們看看你的配置代碼:

pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows); 
if(pAc) 
    pubyPositioner = (UINT8*)malloc(sizeof(UINT8) * i_ubyNoOfCols); 
if(pubyPositioner) 
    for(i = 0; i < i_ubyNoOfCols; ++i) 
     pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);    

所以,你第一次分配內存i_ubyNoOfRows指針。這可以。
這樣就可以進行分配i_ubyNoOfCols字節,(在測試情況下3個字節),但需要對i_ubyNoOfCols*i_ubyNoOfRows整數(3 * 3 * 4 = 36個在測試用例字節空間,假設int是一個32位位類型)。
當你開始初始化你的記憶時,你踩在對malloc()free()至關重要的數據才能正常工作。

你的錯誤的一半的信號是pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);。它顯示你使用了錯誤的類型pubyPostitioner

Ps:即使此函數獲取了作爲參數傳遞的正確寬度和高度,您在Fill2D()中也有兩個3硬編碼。

0

在我的問題中,我想爲2D數組分配內存,然後釋放它。 一些研究之後,我已經解釋過我的理解如下

  1. 使用指針
double **p; 
int i; 
p= malloc(rows * sizeof(*p)); 
for(i= 0; i<rows;++i) 
p[i] = malloc(cols * sizeof(double)); 

... 的陣列分配內存...

for(i=0;i<rows;i++) 
    free(p[i]); 
free(p); 
  1. 分配使用指針查找表
double **p; 
double *elem; 

elem = malloc(rows * cols * sizeof(double)); 
p = malloc(cols * sizeof(double*)); 
for (i = 0; i<rows;++i) 
p[i] = elem + (i*cols); 

free(p); 
  1. 連續分配
double **p; 
p = malloc(rows * cols * sizeof(double*)); 
/*Accessing/printing values ... assume values are assinged to this array*/ 
for(i=0; i <rows; ++i) 
for(j = 0; j< cols; ++j) 
    printf("%d",p[j + (i * cols)]); 

free(p)