简体   繁体   中英

Error in using free with 2D arrays in C

I am using C for this project to create a bunch of dynamically created arrays. They are generated as explained [here][1] This works fine. ' However, when I try the code below to free up the array(s), I get a "segmentation error( Core Duped)". I am using the listing below to create a "my_struct".

typedef struct
{
    uint32_t**  block;         
    uint32_t**  valid;
    uint8_t     block_size;     //Bytes per block

    uint8_t     level;
}my_struct;

my_struct L1, L2;

Thereafter, at a later point, the pointers "block" and "valid" are allocated dynamic memory using the function below where they are successively passed as parameters (arr_ptr):

void Generate2DArray (uint32_t** arr_ptr, uint32_t row, uint32_t column)
{
uint32_t* temp;
uint32_t i = 0;
uint32_t j = 0;

arr_ptr = (uint32_t**)malloc(row* sizeof(uint32_t*));
if(arr_ptr == NULL)
{
    printf("MALLOC 1 FAILS \n ");
}
temp = (uint32_t*)malloc(row* column* sizeof(uint32_t));
if(temp == NULL)
{
    printf("MALLOC 2 FAILS \n ");
}
for (i = 0; i < row; i++)
{
  arr_ptr[i] = temp + (i * column);
}
}

All this works fine so far.

Now, when I try to "free" the memory near the end of the code, using the listing below, I get an error message saying "Segmentation Fault (Core dumped)"

void FreeMemory(uint32_t** arr_ptr, uint32_t rows)
{
    uint32_t i = 0;

    for ( i = 0; i < rows; i++)
    {
        free(arr_ptr[i]);
    }   
    free(arr_ptr);
}

Please provide any suggestions as to where am I going wrong. I have gone through this post as well and my code seems to be compliant with it.

Thanks!!

Hope this helps.:)

       arr_ptr: row*sizeof(uint32_t*)
          ||
          ||
        __\/__       0   1   2   ...   column-1   column
  0    | temp ==>  |   |   |   |     |          |       |: column*sizeof(uint32_t)
  1    | temp             
  2    | temp                
  .    |  ..                 
  .    |  ..                 
row-1  | temp                
 row   | temp            
        ------

Fix you Generate2DArray , you aren't achieving what you're thinking.

void Generate2DArray  (uint32_t*** arr_ptr, uint32_t row, uint32_t column)
{
    int **array= malloc (row * sizeof (uint32_t*));

    for (int i = 0; i < row; i++)
        array[i] = malloc(column * sizeof(uint32_t));

    *arr_ptr = array;

}

Use it using :

int **arr_ptr;
Generate2DArray(&arr_ptr, rows, cols);

You can use your way of single allocation of row buffers, but the main point was the *** , the address of the final arr_ptr . Also, I think this is bit clearer.

You must call free() for each successfull call to malloc(). You are doing two mallocs, so you need to call free two times. Once for arr_ptr and once for temp (which is equivalent to arr_ptr[0]).

If you want to keep your implementation of FreeMemory you must change Generate2DArray so that you call malloc for each row and store the returned pointer in arr_ptr[i]. You should decide if you think it's better to have one larger block of memory or a lot of smaller blocks of memory and then choose the corresponding implementation.

Also: as WhozCraig said you are not returning the allocated buffer to the caller of Generate2DArray. You should change the function signature to one of these:

// Return pointer
uint32_t** Generate2DArray (uint32_t row, uint32_t column);
// Pass pointer to the pointer variable and store it there
void Generate2DArray (uint32_t*** arr_ptr, uint32_t row, uint32_t column);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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