Allocate 2D array in C (not an array of pointers) on the heap

I have a simple question, but the answer seems very difficult to find:

How do I create a true 2D array in C (not C ++), with dynamic size (size unknown at compile time), not an array of pointers on the heap so that I can put this allocation in a separate function and return the allocated array without getting any warnings from gcc -Wall

?

I found many other questions here on SO and other forums, but the answers all had some flaws:

  • I have seen many answers showing how to initialize an array of pointers, which according to some comments can lead to memory fragmentation and need to free the loop when no longer used.
  • I don't want to only have a predefined array size, but I want to use it in some loops, creating large arrays.
  • I don't want the values ​​in the array to be predefined as well, they are calculated at runtime.
  • I read about the layout in memory, which can be different when using certain methods to create the array, while you can still use the array as follows: a[y][x]

    . I want my array to also have a memory layout for a true 2D array.

What is the correct way to achieve selection of such a true 2D array?

EDIT # 1: The return type of an allocation method can be a pointer to an allocated array.

+3


source to share


2 answers


You don't need a special function. Just do it like this

double (*A)[n][m] = malloc(sizeof *A);

      



Starting with the C99, here n

, and m

can be any positive integer expression that you want.

Such a thing is a pointer to a VLA variable length array.

+5


source


I know this is not a perfect answer; but I hope this is helpful.

#include <stdio.h>
#include <stdlib.h>
#define ELEM(myArr,X,Y) (myArr->arr[myArr->cols * X + Y])
#define FREE_MY_ARR(myArr) \
    if(myArr){if(myArr->arr) free(myArr->arr);  free(myArr);}
    typedef struct myArr
    {
        int rows , cols;
        int * arr;
    } myArr;

    myArr * create_my_arr(int rows , int cols)
    {
        myArr * my_arr = malloc(sizeof(myArr));
        my_arr->rows =rows;
        my_arr->cols=cols;
        my_arr->arr= malloc(rows * cols * sizeof(*my_arr->arr));
        return my_arr;
    }

    int main()
    {
        int rows = 4 , cols = 5;
        myArr * my_arr = create_my_arr(4,5);
        int i , j ;
        for(i = 0 ; i < rows;i++)
            for(j = 0 ; j < cols;j++)
            {
                ELEM(my_arr , i , j) = cols * i + j; // 0,1,2,3,4,5,6,7,8,...etc
            }
        //print array.
        for(i = 0 ; i < rows;i++)
        {
            for(j = 0 ; j < cols;j++)
            {
                printf("arr[%d,%d]=%d\t" , i , j , ELEM(my_arr ,i , j));
            }
        printf("\n");
        }
        FREE_MY_ARR(my_arr);
       return 0;
    }

      



output:

   gcc -o s s.c &&s
    arr[0,0]=0      arr[0,1]=1      arr[0,2]=2      arr[0,3]=3      arr[0,4]=4
    arr[1,0]=5      arr[1,1]=6      arr[1,2]=7      arr[1,3]=8      arr[1,4]=9
    arr[2,0]=10     arr[2,1]=11     arr[2,2]=12     arr[2,3]=13     arr[2,4]=14
    arr[3,0]=15     arr[3,1]=16     arr[3,2]=17     arr[3,3]=18     arr[3,4]=19

      

+1


source







All Articles