简体   繁体   English

2D数组的连续内存分配—释放内存

[英]Contiguous memory allocation for 2D array — freeing the memory

I am facing a heap crash during free() when I run this program, but I am successful if I do debug using F10 (in Visual studio 2010). 运行此程序时,我在free()期间遇到堆崩溃,但是如果我使用F10(在Visual Studio 2010中)进行调试,则可以成功。

My piece of code: 我的一段代码:

The below code is used to free. 以下代码用于释放。 Can someone please explain deallocation for 2D array in this case? 在这种情况下,有人可以解释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);  

    }
}

The below code is used for memory allocation: 以下代码用于内存分配:

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;
}

The code to fill array and print array: 填充数组和打印数组的代码:

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;
}

The below code is kind of entry point: 以下代码是一种切入点:

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);   

This is not contiguous memory allocation! 这不是连续的内存分配! It is a pointer-based lookup table which is allocated in one segment, pointing at a chunk of memory allocated in another segment. 它是一个基于指针的查找表,分配在一个段中,指向另一个段中分配的内存块。

Correct code for allocating a true 2D array would be: 分配真正的2D数组的正确代码为:

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

Note that this will only compile on a C compiler, so you can't use Visual Studio. 请注意,这只能在C编译器上进行编译,因此您不能使用Visual Studio。


Can someone please explain deallocation for 2D array in this case? 在这种情况下,有人可以解释2D阵列的释放吗?

free(pAccess); 

Looks like the code only deallocates the pointer lookup table and not the actual data. 看起来该代码仅取消分配指针查找表,而不分配实际数据。 So I suppose that is a bug: the code contains memory leaks. 因此,我认为这是一个错误:代码包含内存泄漏。

Lets take a look at your allocation code: 让我们看一下您的分配代码:

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);             

So, you are first allocating memory for i_ubyNoOfRows pointers. 因此,您首先要为i_ubyNoOfRows指针分配内存。 This is fine. 这可以。
Then you proceed to allocate i_ubyNoOfCols bytes , (3 bytes in your test case), but you need space for i_ubyNoOfCols*i_ubyNoOfRows integers (3*3*4 = 36 bytes in your test case, assuming int is a 32-bit type). 然后,您继续分配i_ubyNoOfCols 个字节 (在测试用例中为3个字节),但是您需要i_ubyNoOfCols*i_ubyNoOfRows 整数的空间(假设int是32位类型,在您的测试用例中3 * 3 * 4 = 36个字节)。
When you proceed to initialize your memory, you trod on data vital for malloc() and free() to function properly. 当您继续初始化内存时,您踩了对malloc()free()正常运行至关重要的数据。

A telltale sign of one half of your mistake is the cast in the line pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols); 您错误的一半的明显迹象是行pAc[i] = (SINT32*)pubyPositioner + (i * i_ubyNoOfCols); . It shows that you used a wrong type for pubyPostitioner . 它表明您为pubyPostitioner使用了错误的类型。

Ps: You have two 3 s hardcoded in Fill2D() , even though this function gets the correct width and height passed as arguments. Ps:即使此函数获得作为参数传递的正确宽度和高度,您在Fill2D()中也有两个3硬编码。

In my question,I wanted to allocate memory for 2D array then free it. 在我的问题中,我想为2D数组分配内存,然后释放它。 After some study, i have explained my understanding as below 经过研究,我解释了我的理解如下

  1. Allocate memory using array of pointers 使用指针数组分配内存
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. allocation using pointer lookup table 使用指针查找表进行分配
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. Contiguous Allocation 连续分配
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM