+ 3
How to return a 2D array?
https://code.sololearn.com/c5ZLmdKNJcgW/?ref=app Here in this program I tried to return a 2D array but it shows errors. Where did I go wrong?
12 Answers
+ 6
The first issue is that a 2D array is not represented by a pointer to int, but rather a pointer to a pointer to int. Instead of int* p, you need int** p. Same goes for the function return type.
The second thing is you'd probably need dynamic memory to make this work (since the 2d array comes from within the function and not passed into it from outside). The following is a working example:
int main() {
int i,j;
int** p=NULL;
p=putarr();
//printing the called array
for(i=0;i<2;i++){
for(j=0;j<3;j++)
printf("%d ",p[i][j]);
printf("\n");
}
}
//returning the 2D array
int** putarr(){
int** row = malloc(2*sizeof(int*));
int* col = malloc(3*sizeof(int));
row[0] = col;
row[1] = col+3;
return row;
}
Remember to free up the memory somewhere ofc.
I feel like a better idea is to just have the function take an empty 2d array, and populate it, something like
void fillarr(int** p) { ... }
+ 6
Martin Taylor Ah, yep. I remember that implementation now. Technically that's a single-dimension array interpreted and utilized as a multidimensional array, but I imagine the odds are one would use that over the less readable pointer to pointer.
+ 5
Martin Taylor Thanks for the clarification! Definitely agree with your pov there... I guess I should have made mine clearer. While multidimensional arrays do not exist in terms of how the physical memory blocks are structured, I am fairly sure C/C++ distinguishes between int* p and int** p. I think that's what I was referring to when talking about how one would "store a multidimensional array".
However, on your claim that [][] is simply syntactic sugar, and that what we really have here is similar to a pointer to int (instead of a pointer to pointers of int), my observations appear to contradict them:
int test[1][1] = {{1}};
printf("%d", test[0]);
This gave me a memory address, which should mean that 'test' is indeed a pointer to pointers of int. Are we talking about implementations which are compiler dependent here? If it was indeed a pointer to int, wouldn't I expect the value 1 to be returned by invoking test[0]?
+ 4
Martin Taylor I mean, the compiler does interpret test[0] as a pointer in the given context... but I concede. I understand now that arrays are different from pointers since pointers are effectively variables with their own unique addresses, while arrays are just the address of the first element they store.
By the way, is there anything preventing us from using dynamically allocated memory to construct 2D arrays, which would result in test, test[0] and test[0][0] in fact pointing to different memory addresses?
int** test = malloc(sizeof(int*));
int* p = malloc(sizeof(int));
test[0] = p;
p[0] = 1;
printf("%p\n", &test[0]);
printf("%p\n", &test);
printf("%p\n", &test[0][0]);
I understand nobody does this, but just for the sake of discussion wouldn't test be considered a 2D array, where test[0] is an actual pointer to int? Is test an entirely different construct now which the compiler handles differently from a "normal" 2D array?
+ 3
Here's how you do it:
char (*foo(int a))[3] {
static char str[2][3];
return str;
}
/* char arr[m][n] -> *(*(arr + m) + n)
Here, the first pointer if of the type 'char (*)[n] while the dereferenced one is of the type 'char *'. */
// Hope this helps
+ 1
Hatsy Rei Thanks a lot for helping me out. But I'm not familiar with the concept of dynamic memory, so I will surely look into this again when I learn about it in near future.
+ 1
Calvin Thomas could you explain it more elaborately coz I couldn't clearly understand what ur code does here.
I mean why do we use char and then use *int as its parameters?
+ 1
Hatsy Rei Nope, they're not the same. Let's consider this code:
//1
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
/*
A 24-byte array is created in the stack. 'arr' acts as a const pointer to it. Now, 'arr' is of the type 'int (*)[3]', meaning that incrementing it will increase the value by 3 * 4 bytes. Dereferencing this pointer will result in another pointer of type 'int *'. Incrementing this by 1 raises its value by 4 bytes.
*/
I hope that you can understand the difference between this one and your code. I hope that I haven't gone wrong. If I unfortunately typed something incorrect, feel free to correct me.