0

Is this the correct method to define an 5*3 matrix using double pointers?`

 int **M1;
 M1 = (int **)malloc(5 * sizeof(int *));
 for (i=0;i<5;i++)
 {
    M1[i] = (int *)malloc(3 * sizeof(int));
 }`

If so, how can I assign M1[3][15] = 9 in the code and still get no error? And why am I getting a segmentation error in assigning M1[6][3]=2?

I understood after few such initializations that I created a 5*xx array, i.e. I couldn't go above 5th row but I could assign any value to the number of columns. How should I create just a 5*3 array?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
re3el
  • 735
  • 2
  • 12
  • 28
  • 4
    Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Aug 13 '15 at 10:57
  • 2
    If you go out of bounds you will have *undefined behavior*. The C language has no bounds checking, it allows you to [shoot yourself in the foots](http://idioms.thefreedictionary.com/shoot+in+the+foot) as much as you like. Just don't do it. – Some programmer dude Aug 13 '15 at 10:58
  • @JoachimPileborg: I was able to go out of bounds by extending rows not columns. I was confused as to how did it happen. I don't intend to go out of bounds. – re3el Aug 13 '15 at 11:01

2 Answers2

1

In your code, you're allocating memory for 5 pointers

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

and later, you're trying to access beyond that, based on an unrelated value of m

for (i=0;i<m;i++)

when m goes beyond 4, you're essentially accessing out of bound memory.

A better way to allocate will be

int m = 5;
M1 = malloc(m * sizeof(*M1));
if (M1) 
{
 for (i=0;i<5;i++)
 {
    M1[i] = malloc(3 * sizeof(*M1[i]));
 }
}

couldn't go above 5th row but I could assign any value to the number of columns.

NO, you can not. In any way possible, accessing out of bound memory invokes undefined behaviour.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

Since Sourav tackled the UB case, I'll answer

How should I create just a 5*3 array?

Why not rely on automatic variables? Unless you've a compelling reason not to, use them

int matrix[5][3];

If you don't know the dimensions in advance, and don't prefer doing the double pointer manipulation, flatten it like this:

int *m = malloc(sizeof(int) * rows * cols);
// accessing anything from 0 to (rows * cols) - 1 is permitted

// helper to make usage easier
int get_element(int *m, int i, int j, int cols) {
    return m[i * cols + j];
}

OTOH, if you only don't know the first dimension at compile-time, then you may do:

typedef int (Int5) [5];   // cols known at complie-time
int rows = 3;
Int5 *r = malloc(rows * sizeof(Int5));
r[0][0] = 1;   // OK
r[0][5] = 2;   // warning: out of bounds access

With this method you get a bit more type safety due to the compiler knowing the size in advice.

legends2k
  • 31,634
  • 25
  • 118
  • 222