0

My task is to make a 2D array 2xn from values given in A and B which have n elements.

I found this way to allocate memory for 2D array and it works but I don't understand if or why it is correct

int **tab2D(int A[],int B[],int n)
{
    int **newTab = malloc(n*sizeof(int*));
    newTab[0] = A;
    newTab[1] = B;
    return newTab;
}

I know there are other ways to do this but I'm curious about this one.

Mateusz
  • 87
  • 1
  • 8
  • because malloc returns contiguous memory. – Sourav Ghosh Aug 28 '18 at 09:07
  • Duplicate: [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Aug 28 '18 at 09:13
  • 2
    Possible duplicate of [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Thomas Flinkow Aug 28 '18 at 09:14

2 Answers2

0

As I understand your code it should work like this.

int **tab2D(int A[],int B[],int n)

can be seen as

int **tab2D(int *A,int *B, int n)

so you pass pointers to the two arrays which are already allocated. You then allocate some memory for the pointers-to-pointers

 int **newTab = malloc(n*sizeof(int*));

which I think should be

 int **newTab = malloc(2*sizeof(int*));

instead, because you have A and B, which are both the same length n, I assume. Then you dereference the new pointer-to-pointers and assign the pointers to your arrays

newTab[0] = A;
newTab[1] = B;

which could be written as

*newTab = A;
*(newTab + 1) = B;
meetaig
  • 913
  • 10
  • 26
0

This is not a 2D array of ints, is an array of pointers to int.

It works because each element of the array points to an address containing an array of ints

A similar code using the stack, just to show why it works:

int a[] = {1, 2};
int b[] = {3, 4};
int *arr[] = {a, b};

A real 2D array is supposed to work in contiguous areas (without fragmentation), you can use pointers to VLA's to achieve this:

int rows, cols;

scanf("%d %d", &rows, &cols);

int (*arr)[cols] = malloc(sizeof(int [rows][cols]));
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
  • Voted down because putting the code shown in this answer, `int *arr[] = {a, b};`, into the OP’s function would break the program, as the function returns the array, but the `arr` of `int *arr[] = {a, b};` ceases to exist when the function returns. – Eric Postpischil Aug 28 '18 at 11:27
  • Additionally, it is questionable whether the statement that “This [a pointer to a pointer to `int`] is not a 2D array…” is true. Neither a pointer to a pointer nor an array of arrays is a first-order (that is, an entity built into the language) two-dimensional array in C. But both function as a two-dimensional array, and it is as legitimate to describe them as a two-dimensional array as it is to describe `double sec(double x) { return 1/cos(x); }` as a secant function even though C has no built-in secant function. We can make new things out of other things, including two-dimensional arrays. – Eric Postpischil Aug 28 '18 at 11:33
  • @EricPostpischil: Even if you can use subset array notation in the OPs code, it is not a 2D array (as the title suggests), arrays must be placed in contiguous areas. The snippet was an example of an analogue code and was not intended to be used as a replacement. – David Ranieri Aug 28 '18 at 12:36
  • (a) An object that behaves like a two-dimensional array serves the purposes of a two-dimensional array and is a two-dimensional array. As I wrote, it is not a two-dimensional array built-in to the language as an element. it is constructed. A thing that is constructed nonetheless exists. (b) If the code was intended as an example and not intended to be used as a replacement, that should be stated. Readers, especially novices who are just learning these concepts, cannot be expected to read your mind. As the answer currently stands, “Your code could also be written as…”, it misleads the reader. – Eric Postpischil Aug 28 '18 at 14:00
  • _An object that behaves like a two-dimensional array serves the purposes of a two-dimensional array and is a two-dimensional array._ No, it is important to call things by their name, my example using VLAs is a real 2D array, OPs is not, you can confirm what I say in any definition of what an array is. – David Ranieri Aug 28 '18 at 14:10
  • I believe (but Im not pretty sure) that OPs construction is usually called look-up table. – David Ranieri Aug 28 '18 at 14:20
  • You are right about the second point, it can be mislead. Edited. – David Ranieri Aug 28 '18 at 14:36
  • I am calling a thing by its name. `int B[4][5]` is a two-dimensional array. It is an array. It has two dimensions. It is laid out in memory as a two-dimensional array. It is **constructed** in C by making an array of arrays. The result of the construction is a two-dimensional array. It is addressed in two dimensions. The fact that it is a constructed two-dimensional array instead of an atomically native two-dimensional array does not change what it **is**, only **how** it was made. A building constructed of bricks is a building, not just bricks. When you make a new thing, you have a new thing. – Eric Postpischil Aug 28 '18 at 15:23