The loop in C should be

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

Otherwise the first row will be left unallocated.

After this change has been done, the java code is almost the same as the C code. Change malloc to calloc (for zero initialization of the allocated memory) to get the equivalent of the java code.

Answer from Spikatrix on Stack Overflow
๐ŸŒ
Learningc
learningc.org โ€บ chapters โ€บ chapter09-multi-dimensional-arrays โ€บ 2d-dynamic-memory-alloc
9.3. Dynamic Memory Allocation of 2D Arrays โ€” Snefru: Learning Programming with C
Third, we can access the elements as any 2D array. Forth, we free only the dynamically allocated three 1D arrays. #include <stdlib.h> int main(void) { // on Stack, statically have allocate 3 pointers, // each will point to a 1D array corresponding to a row int* arr[3]; // Access each pointer and make it point // to a newly dynamically allocated array for (int row = 0; row < 3; row++) { arr[row] = (int*)malloc(4 * sizeof(int)); } // Access elements as usual for (int row = 0; row < 3; row++) { for (int col = 0; col < 4; col++) { arr[row][col] = row * 4 + col + 1; } } // Free only dynamically allocated space for (int row = 0; row < 3; row++) { free(arr[row]); } return 0; }
๐ŸŒ
Diveintosystems
diveintosystems.org โ€บ book โ€บ C2-C_depth โ€บ arrays.html
2.5.1. Single-Dimensional Arrays
Like 1D dynamically allocated arrays, the pointer variable for a 2D array is allocated on the stack. That pointer is then assigned the value returned by the call to malloc, which represents the base address of the contiguous chunk of NxM int storage locations in the heap memory.
Discussions

from c malloc matrix to java array - Stack Overflow
Why should you go form 0? Why Array index start from '0' [sorry pasting the same link but it's kind of relevant] ... In C double **a; creates a pointer to a pointer and with a malloc you get a multi-dimensional array. More on stackoverflow.com
๐ŸŒ stackoverflow.com
July 26, 2015
c - How to use malloc on a 2D integer array - Stack Overflow
How do I define a 2D array where the first dimension is already defined with MAX_VALUES. I wish to be able to allocate memory to the second dimension. Below is what I have attempted. I want an arra... More on stackoverflow.com
๐ŸŒ stackoverflow.com
Malloc a 2D array in C - Stack Overflow
Every time I allocate the memory for a 2D array first I create an array of int** and then with a for I allocate the memory for each element. For example: int ** arr = malloc(N*sizeof(int *)); for... More on stackoverflow.com
๐ŸŒ stackoverflow.com
c - defining a 2D array with malloc and modifying it - Stack Overflow
How do i define a 2D array using malloc ? (lets say 10X20). second, can i increase number of rows or cols without creating a new increased array and copying all data to it? for instance, how do i More on stackoverflow.com
๐ŸŒ stackoverflow.com
November 16, 2011
๐ŸŒ
Brainly
brainly.com โ€บ computers and technology โ€บ high school โ€บ how can you allocate memory for a 2d array using `malloc()` and a single pointer?
[FREE] How can you allocate memory for a 2D array using `malloc()` and a single pointer? - brainly.com
January 25, 2024 - ... To allocate a 2D array using malloc() and a single pointer, first create an array of pointers to represent the rows, and then allocate memory for each row individually. Finally, access the elements using indices and remember to free the ...
๐ŸŒ
Eskimo
eskimo.com โ€บ ~scs โ€บ cclass โ€บ int โ€บ sx9b.html
23.2: Dynamically Allocating Multidimensional Arrays
#include <stdlib.h> int **array; ... NULL) { fprintf(stderr, "out of memory\n"); exit or return } } array is a pointer-to-pointer-to-int: at the first level, it points to a block of pointers, one for each row....
Top answer
1 of 3
1

The loop in C should be

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

Otherwise the first row will be left unallocated.

After this change has been done, the java code is almost the same as the C code. Change malloc to calloc (for zero initialization of the allocated memory) to get the equivalent of the java code.

2 of 3
0

The way I see matrix initialisation in C is this:

1.You allock N blocks-representing the lines
2.THen you go ot each line and say:ok,you are getting M values

I know this is kinda redundant to what you just wrote but when you look at the 2 different ways of initialising a matrix you see the 2 main differences:

  1. malloc,just says here there will be something of this type[even if you cna't really say there are types in C]
  2. calloc,goes one step forward and initialises everything,putting the default value over there - you could see it as the first step closer to JVM

Java,can be seen as a layer on top of the compiler.A layer as in you don;t have to worry about the way it sets a value just that you will have something in that address. One more thing you should always remember about JVM is that a value is no longer there when it is Null [don't forget this little guy here,as you wil lface this issue many many times]

as to your first question: you don;t need to go M+2+1 for the number of lines you should go M+2[last element] -0[first element] +1 ,this is the actual way you calculate the number of elements an array has so that is why your for should start from that position.

Why should you go form 0? Why Array index start from '0' [sorry pasting the same link but it's kind of relevant]

Find elsewhere
๐ŸŒ
Nerd Paradise
nerdparadise.com โ€บ programming โ€บ create2darray
Creating a 2D Array in Java, C#, Python, JavaScript, and C : Nerd Paradise
Since an array is really just a pointer to the first item in the array and a grid is an array of arrays, the type for a 2D grid of integers is int**. Of course you'd write this with a loop, but for the sake of brevity... int** grid = (int**) malloc(sizeof(int*) * 2); grid[0] = malloc(sizeof(int) * 3); grid[1] = malloc(sizeof(int) * 3); printf("bottom right corner contains a %d\n", grid[1][2]); Please note that describing C's syntax as being "similar to C# and Java's syntax" was a call to arms for people to shout angrily in the comment thread about how Java and C# copied C.
Top answer
1 of 7
11

10x30:

int(*array)[30] = malloc((sizeof *array) * 10);

15x20:

int(*array)[20] = malloc((sizeof *array) * 15);

Resizing to 20x25:

int(*array2)[25] = realloc(array, (sizeof *array2) * 20);

The outer dimension (10, 15, 20) can be determined at runtime, because it's not need as part of index calculations by the compiler. The inner dimension (30, 20, 25) needs to be known at compile time. Hope it helps.

Note that unlike the array-of-pointer solutions, this one can be handled as a single block of memory, because it allocates everything in a single chunk of memory like a real declared array:

memcpy(somewhere, array2, sizeof(int) * 20 * 25); // (sizeof *array2) * 20

It ultimately depends on your usecase, though.


Since some people have difficulties understanding the actions taken by an index operation to array, let's what Clang gives us for an index expression in the following code

int main() {
  int(*array)[10] = malloc((sizeof *array) * 5);
  array[4][9] = 0;

  int(*array1)[10][5] = malloc((sizeof *array1) * 20);
  array1[19][9][4] = 0;
}

It's a nice compiler, which can print its AST in an easily readable manner

  // array[4][9] = 0;
  (BinaryOperator 0xba62cc0 <line:5:3, col:17> 'int' '='
    (ArraySubscriptExpr 0xba62c80 <col:3, col:13> 'int'
      (ImplicitCastExpr 0xba62c60 <col:3, col:10> 'int *' <ArrayToPointerDecay>
        (ArraySubscriptExpr 0xba62c20 <col:3, col:10> 'int [10]'
          (DeclRefExpr 0xba62bdc <col:3> 'int (*)[10]' Var='array' 0xba62a00)
          (IntegerLiteral 0xba62c00 <col:9> 'int' 4)))
      (IntegerLiteral 0xba62c40 <col:12> 'int' 9))
    (IntegerLiteral 0xba62ca0 <col:17> 'int' 0))

  // array1[19][9][4] = 0;
  (BinaryOperator 0xba630b8 <line:8:3, col:22> 'int' '='
    (ArraySubscriptExpr 0xba63078 <col:3, col:18> 'int'
      (ImplicitCastExpr 0xba63058 <col:3, col:15> 'int *' <ArrayToPointerDecay>
        (ArraySubscriptExpr 0xba63018 <col:3, col:15> 'int [5]'
          (ImplicitCastExpr 0xba62ff8 <col:3, col:12> 'int (*)[5]' <ArrayToPointerDecay>
            (ArraySubscriptExpr 0xba62fa0 <col:3, col:12> 'int [10][5]'
              (DeclRefExpr 0xba62f5c <col:3> 'int (*)[10][5]' Var='array1' 0xba62db0)
              (IntegerLiteral 0xba62f80 <col:10> 'int' 19)))
          (IntegerLiteral 0xba62fc0 <col:14> 'int' 9)))
      (IntegerLiteral 0xba63038 <col:17> 'int' 4))
    (IntegerLiteral 0xba63098 <col:22> 'int' 0)))

Note that each array subscript expression takes a pointer, adds the value of the index, and yields the addressed element. If that subelement is an array, it is decayed to a pointer to its first element. This is really not actually different than the steps done for a declared array

int main() {
  int array[5][10] = { };
  array[4][9] = 1;
}

Yields a very similar AST, with just the most inner expression first being decayed to a pointer to its first element

  // array[4][9] = 1;
  (BinaryOperator 0xbf9f7e8 <line:5:3, col:17> 'int' '='
    (ArraySubscriptExpr 0xbf9f7a8 <col:3, col:13> 'int'
      (ImplicitCastExpr 0xbf9f788 <col:3, col:10> 'int *' <ArrayToPointerDecay>
        (ArraySubscriptExpr 0xbf9f748 <col:3, col:10> 'int [10]'
          (ImplicitCastExpr 0xbf9f728 <col:3> 'int (*)[10]' <ArrayToPointerDecay>
            (DeclRefExpr 0xbf9f6cc <col:3> 'int [5][10]' Var='array' 0xbfa81f0))
          (IntegerLiteral 0xbf9f6f0 <col:9> 'int' 4)))
      (IntegerLiteral 0xbf9f768 <col:12> 'int' 9))
    (IntegerLiteral 0xbf9f7c8 <col:17> 'int' 1)))
2 of 7
4

While malloc() does not directly support multi-dimensional arrays, there are workarounds, such as:

int rows = 10;
int cols = 30;
int *array = malloc(rows * cols * sizeof(int));

// Element (5,6)
int x = 5;
int y = 6;
int element = array [ x * cols + y ];

While this isn't directly a 2D array, it works, and in my opinion it's the simplest. But if you want to use the [][] syntax instead, you would have to make pointers to pointers, for instance:

int rows = 10;
int cols = 30;
// Rows
int **array = malloc(rows * sizeof(int*));
// Cols
int i;
for(i = 0; i < rows; i++)
  array[i] = malloc(cols * sizeof(int));

// Element (5,6)
int x = 5;
int y = 6;
int element = array[x][y];
๐ŸŒ
Richard Johnsonbaugh
condor.depaul.edu โ€บ ~ggordon โ€บ courses โ€บ 211 โ€บ 212doc โ€บ TwoDimensionalArrays.htm
Two Dimensional Arrays in Java
In memory, it will look like, assuming the array starts at address 200: 200 204 208 212 216 220 224 228 232 236 240 244 248 252 256 ยท So table[2][3] is at address 200+2*4*5+4*3 = 252. However, in Java, one allocates a table of addresses, just as for an array of objects.
๐ŸŒ
Reddit
reddit.com โ€บ r/c_programming โ€บ malloc() question for 2d array
r/C_Programming on Reddit: malloc() question for 2d array
November 8, 2020 -

I am confused as to how and what malloc() is exactly doing/making with my specific line.

I am trying to allocate for a game board.

I have the lines:

char *board;
int length = 7;
int height = 6;
board = (char*)malloc(length * height * sizeof(char));

printf("%lu\n", sizeof(board));  //to test the size of my board

The board results as having a size of 8, which confuses me because I am intending it to have a size of 42 (7 * 6 = 42). I think I remember reading somewhere that for 2d arrays in C, the coordinates of an index are interpreted as if it were a 1d array. So a row of 7, col of 6 would just go to a size of 42 (or something of the sort? I feel I have something wrong about this).

For comparison, the code:

char board[7][6]
printf("%lu", sizeof(board));

gives me a resulting board size of 42 as expected.

So can anyone explain to me what it is I am doing wrong with malloc? What is the difference between the two ways I am creating a 2d array board, one being through malloc, the other through the statement char board[7][6]; ?

๐ŸŒ
Sololearn
sololearn.com โ€บ en โ€บ Discuss โ€บ 116505 โ€บ how-can-i-create-a-2d-dynamic-array-using-malloc-in-c
How can I create a 2D dynamic array using malloc() in C? | Sololearn: Learn to code for FREE!
int **arr = (int **)malloc(row * sizeof(int *)); for (i=0; i<row; i++) arr[i] = (int *)malloc(column * sizeof(int)); for more details check out: http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ 4th Dec 2016, 3:20 AM ยท Nikunj Arora ...
Top answer
1 of 5
5

I'll assume you meant to write something like:

int[][] array = new int[5][];  // this compiles

Now, to answer your question: The variable array is just a reference; the memory is consumed by whatever it points to. In this case, it points to an array of int[]s. Specifically, it points to an array of references, each of which points to an int[]:

                  +-----+-----+-----+-----+-----+
array ----------> | [0] | [1] | [2] | [3] | [4] |
                  +-----+-----+-----+-----+-----+
                     |     |     |     |     |
                     |     |     |     |     |
                     |     |     |     |     |
                     v     v     v     v     v
                  +-----+ ...   ...   ...   ...
                  |  0  | 
                  +-----+
                  |  0  |   
                    ...

The horizontal array is first allocated with new int[5][] (which consumes memory). Then, as you allocate each individual integer array in getMeArray(), memory is consumed further. This is a runtime phenomenon.

2 of 5
1

Now, is the memory allocation done on compile time, because it should be done as per my understanding

No, that's how it works in C. Java arrays are completely different!

but I am not sure how to figure out how much should be allocated to array.

You mean how much memory will be allocated to the array?

A multidimensional array is an array of references to array objects.

A reference to an object takes up a fixed amount of space, let's say B bytes. An int array takes approximately 4 bytes per integer, plus an additional 4 bytes for storing its size (as is the case for all Java arrays). So for your example it will be 5*B + 4 + 4 times the size of each sub-array + 4, for each sub-array. The sub-arrays are only allocated when actually created by your program. This is true for all arrays, they are only allocated when created by your program. My calculation assumes that the whole thing, including the sub-arrays, has already been created.

Top answer
1 of 5
4

You say in the comments that n is the number of rows. So you need to allocate n rows each of length m. Therefore, the second for loop condition should be i < n. Also, you should check the return value of malloc for NULL in case it fails to allocate memory. I suggest the following change -

long long **a = malloc(n * sizeof(*a));
for (i = 0; i < n; i++) {
    a[i] = malloc(m * sizeof(*a[i]));
}

Please note that a multi-dimensional array is not a fundamentally new type. It's simply an array of elements where each element itself is an array (for a 2D array), an array of arrays (for a 3D) array and so on. If you are using C99, you can allocate your array cleanly and succinctly as

int nrow = 4;  // number of rows
int ncol = 8;  // number of columns

// define arr to be a pointer to an array of ncol ints, i.e.,
// arr is a pointer to an object of type (int[ncol])
int (*arr)[ncol] = malloc(sizeof(int[nrow][ncol]));

// check the result of malloc for NULL
if (arr == NULL) {
    printf("malloc failed to allocate memory\n");
    // handle it
}

// do stuff with arr
for (int i = 0; i < nrow; i++) {
    for (int j = 0; j < ncol; j++) {
        arr[i][j] = i + j;
    }
}
// after you are done with arr
free(arr);

You should also go through this - How do I work with dynamic multi-dimensional arrays in C?

2 of 5
1

You have three errors: The first is that you allocate only 5 secondary arrays, but in the input you loop over 6 of them.

The second problem is that array indices are zero-based, i.e. the index start at zero and goes to the size minus one.

The third problem is that you scan for two numbers (why?), but you provide only one destination pointer to scanf.

๐ŸŒ
Vaia
vaia.com โ€บ dynamic allocation of array in c
Dynamic Allocation of Array in C: Techniques & Examples - Vaia
Using nested loops and array indexing (e.g., array[i][j]) What is the primary step in achieving dynamic memory allocation for an array of pointers? Declare a pointer to the array of pointers and then allocate memory for the desired number of pointers using malloc.
๐ŸŒ
Ars OpenForum
arstechnica.com โ€บ forums โ€บ operating systems & software โ€บ programmer's symposium
2D array in C - Implimenting with malloc | Ars OpenForum
August 24, 2011 - T **arr = malloc(SIZE1 * sizeof *arr); // allocates a SIZE1-array of pointer to T. if (arr) { int i; for (i = 0; i < SIZE2; i++) { int j; arr[i] = malloc(SIZE2 * sizeof *arr[i]); // allocates a SIZE2-array of T. for (j = 0; j < SIZE2; j++) { arr[i][j] = some_initial_value(); } } } Pros: you ...
๐ŸŒ
Reddit
reddit.com โ€บ r/c_programming โ€บ dynamic allocation of 2d array with malloc()
r/C_Programming on Reddit: dynamic allocation of 2d array with malloc()
November 10, 2020 -

I asked a question on here yesterday about dynamically allocating memory for a 2d array (Hi anyone who saw this and helped me yesterday). The lines I used to do so are:

char *board;
int length = 7;
int height = 6;
board = (char *)malloc(length * height * sizeof(char));

I was told that according to this, i should have allocated memory for 42 chars, i imagine as an array pointed to by board.

However when i test to see if the size maxes out at 42 with lines:

board[43] = 'a';
printf("%c", board[43]);

it throws no errors, and prints successfully meaning it is storing char a at the 43rd index of board.

I also tested it with random high index values subbing in 3000 and it still works.

I also tested it with

(*(board + 3000)) = 'a';

which is another way i've been shown to reference the array memory created with malloc. The result is the same in successfully storing and printing a.

Does anyone know what the issue is and what is going on? By the way I create board with malloc(), it should have a max of 42 indices right?

Edit: Just wanna say thanks for everyone who responded and gave some help :).