4

I tried to make a dynamic 5x5 int array

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

But I get segmentation fault on trying to access it.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • That will only allocate 25 bytes. If you want your array to hold 25 integers multiply by sizeof int. – bruceg Nov 19 '15 at 18:39

5 Answers5

7

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

Yash Gupta
  • 578
  • 6
  • 15
  • 5
    casting the result of `malloc` is not recommended and not needed – Manos Nikolaidis Nov 19 '15 at 18:26
  • why is it not recommended? –  Nov 19 '15 at 18:30
  • @MeghanRagroe Not casting the result of malloc is also not recommended and is also not needed. – this Nov 19 '15 at 18:32
  • This is getting confusing... the linked question is helpful for this though..I think I might use some C++ features also so keeping the casting looks fine –  Nov 19 '15 at 18:36
  • 1
    In general an explicit cast is kind of x-raying the type system and reinterpreting what bits and bytes mean. While this has to occur anyway even in the implicit case, it's a heavy-handed and dangerous weapon. To do considerably more of it than necessary carries the risk that someone will get hurt. If the compiler can do things safely and unambiguously and efficiently for you, there's no need to try to replace its job with human hands. Of course if you plan to port to C++, that's a whole separate story since there the cast is required (but probably you shouldn't use `malloc` there for this). –  Nov 19 '15 at 18:42
4

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));
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
3

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 );
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

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.
John Bode
  • 119,563
  • 19
  • 122
  • 198
-1

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)

S.A.Parkhid
  • 2,772
  • 6
  • 28
  • 58
  • Your code is not allocating the memory as is shown in the picture. – this Nov 19 '15 at 18:43
  • @this , I have not saying that picture has relation to the code , the description for picture is located on below of that . – S.A.Parkhid Nov 19 '15 at 18:58
  • What I was saying is that your code is not correct. – this Nov 19 '15 at 19:06
  • @this , I have flagged your first comment because your reason and for your down vote , where is wrong ? if you are meaning szMatrix , it is an optional parameter , he can set it to 5 or any other number – S.A.Parkhid Nov 19 '15 at 19:29
  • Code clearly only allocates memory for pointers and nothing more. That is simply not a staggered 2d array, as is requested by OP. – this Nov 19 '15 at 19:45
  • please read some c/c++ books again , it works correctly , the first answer by @Yash Gupta in this question and also the answer of 'Vlad from Moscow' uses same methods as I mentioned. – S.A.Parkhid Nov 19 '15 at 19:51