user5582674
user5582674

Reputation:

How can i use dynamic 2d array in c

I tried to make a dynamic 5x5 int array

int **data=malloc(5*5);

But I get segmentation fault on trying to access it.

Upvotes: 4

Views: 192

Answers (5)

John Bode
John Bode

Reputation: 123458

If you want to treat the array as a 2D array (a[i][j]) and you want all the array elements to be contiguous in memory, do the following:

int (*data)[5] = malloc( sizeof *data * 5 );

If you also want to be table to determine the size of the array at run time and your compiler supports variable-length arrays1:

size_t rows, cols;
...    
int (*data)[rows] = malloc( sizeof *data * cols );2

If your compiler does not support VLAs and you still want to determine the array size at runtime, you would do:

size_t rows, cols;
...
int **data = malloc( sizeof *data * rows );
if ( data )
{
   for ( size_t i = 0; i < rows; i++ )
   {
     data[i] = malloc( sizeof *data[i] * cols );
   }
}

The downside of this approach is that the rows of the array are not guaranteed to be contiguous in memory (they most likely won't be). Elements within a single row will be contiguous, but rows will not be contiguous with each other.

If you want to determine the array size at runtime and have all the array elements be contiguous in memory but your compiler does not support variable-length arrays, you would need to allocate a 1D array and manually compute your indices (a[i * rows + j]):

int *data = malloc( sizeof *data * rows * cols );


1. VLAs were introduced with C99, but then made optional in C2011. A post-C99 compiler that does not define the macro __STDC_NO_VLA__ should support VLAs.

2. Caution - there is some question whether sizeof *data is well-defined in this example; the sizeof expression is normally evaluated at compile time, but when the operand is a VLA the expression is evaluated at run time. data doesn't point to anything yet, and attempting to dereference an invalid pointer leads to undefined behavior. All I can say is that I've used this idiom a lot and never had an issue, but that may be due more to bad luck than design.

Upvotes: 0

Yash Gupta
Yash Gupta

Reputation: 588

You need to allocate memory for the 2d-array you want to make (which I think you understand). But first, you will have to allocate the space for pointers where you will store the rows of the 2D-array.

int **data=(int**)malloc(sizeof(*data)*5); //Here 5 is the number of rows

Now you can allocate space for each row.

for(int r=0;r<5;r++){
  data[r]=(int*)malloc(sizeof(**data)*5);//here 5 is the width of the array
}

If you want contiguous block of memory for the whole array, you can allocate a single dimension array of size 25, and access it like data[r*5+c].

PS: Instead of sizeof(*data) and sizeof(**data), you can use sizeof(int*) and sizeof(int) to avoid confusion with *

PS: If you are not using C++, removing the casts from return value of malloc is better (see comments).

Upvotes: 7

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

There are two possibilities. The first one is indeed to allocate a two-dimensional array:

int ( *data )[5] = malloc( 5 * 5 * sizeof( int ) );

In this case one contiguous extent is allocated for the array.

The second one is to allocate at first a one-dimensional array of pointers and then allocate one-dimensional arrays pointed to by the already allocated pointers.

For example

int **data = malloc( 5 * sizeof( int * ) );
for ( size_t i = 0; i < 5; i++ )
{
    data[i] = malloc( 5 * sizeof( int ) );
}

In this case there are allocated in fact 6 extents of memory: one for the array of the pointers and other 5 for arrays of integers.

To free the allocated memory in the first example it is enough to write

free( data );

and in the second example you need to write the following

for ( size_t i = 0; i < 5; i++ ) free( data[i] );
free( data );

Upvotes: 3

S.A.Parkhid
S.A.Parkhid

Reputation: 2868

Here is the answer:

int ** squaredMatrix;
int szMatrix=10;
squaredMatrix= (int**)malloc(szMatrix*sizeof(int*));

for making 2d arrays you should view them as one array which every block is an array again . enter image description here

for example in above picture , blue blocks make an array which each blue block is pointing to an array ( every 4 green blocks in a row are an array and blue blocks in a column are the main array)

Upvotes: -1

Manos Nikolaidis
Manos Nikolaidis

Reputation: 22224

If you want a single contiguous memory block to hold 5x5=25 integers :

int *data = malloc(5*5*sizeof(*data));

If you want a 2d array with size 5x5

int **data = malloc(5*sizeof(*data));
for (int i=0; i<5; ++i)
    data[i] = malloc(5*sizeof(**data));

Upvotes: 4

Related Questions