[英]Contiguous memory allocation for 2D array — freeing the memory
運行此程序時,我在free()期間遇到堆崩潰,但是如果我使用F10(在Visual Studio 2010中)進行調試,則可以成功。
我的一段代碼:
以下代碼用於釋放。 在這種情況下,有人可以解釋2D陣列的釋放嗎?
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 Allocate2D (
SINT32 ***pAccess,
UINT8 i_ubyNoOfRows,
UINT8 i_ubyNoOfCols )
{
SINT32 nResult = -1;
SINT32 **pAc = NULL;
UINT8 *pubyPositioner;
UINT32 unTotalSize;
int i;
//unTotalSize = i_ubyNoOfRows * i_ubyNoOfCols;
printf ( "\nAllocate 2D Array..................\n" );
/* Include the code to allocate the 2D array */
{
/*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);
*pAccess = pAc;
/*Non contugious allocation*/
/*
pAc = (SINT32**)malloc(sizeof(SINT32*) * i_ubyNoOfRows );
*pAccess = pAc;
if(pAc)
for(i= 0; i < i_ubyNoOfRows; ++i){
pAc[i] = (SINT32*)malloc(sizeof(SINT32*) + (i * i_ubyNoOfRows) );
if(pAc[i])
for(j = 0; j < i_ubyNoOfCols; ++j)
pAc[i][j] = (UINT8)malloc(sizeof(UINT8) + (i_ubyNoOfRows * i_ubyNoOfCols) );
}
*/
if(*pAccess != NULL)
nResult = 0;
}
if ( NULL == pAccess )
{
printf ( "%d>Invalid Params\n", __LINE__ );
return -1;
}
return nResult;
}
填充數組和打印數組的代碼:
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 );
}
}
}
}
/*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);
這不是連續的內存分配! 它是一個基於指針的查找表,分配在一個段中,指向另一個段中分配的內存塊。
分配真正的2D數組的正確代碼為:
SINT32 (*pAc)[ubyNoOfCols] = malloc( sizeof(SINT32[i_ubyNoOfCols][i_ubyNoOfRows]) );
...
free(pAc);
請注意,這只能在C編譯器上進行編譯,因此您不能使用Visual Studio。
在這種情況下,有人可以解釋2D陣列的釋放嗎?
free(pAccess);
看起來該代碼僅取消分配指針查找表,而不分配實際數據。 因此,我認為這是一個錯誤:代碼包含內存泄漏。
讓我們看一下您的分配代碼:
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
整數的空間(假設int
是32位類型,在您的測試用例中3 * 3 * 4 = 36個字節)。
當您繼續初始化內存時,您踩了對malloc()
和free()
正常運行至關重要的數據。
您錯誤的一半的明顯跡象是行pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols);
。 它表明您為pubyPostitioner
使用了錯誤的類型。
Ps:即使此函數獲得作為參數傳遞的正確寬度和高度,您在Fill2D()
中也有兩個3
硬編碼。
在我的問題中,我想為2D數組分配內存,然后釋放它。 經過研究,我解釋了我的理解如下
- 使用指針數組分配內存
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);
- 使用指針查找表進行分配
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);
- 連續分配
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.