+ 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?

17th Jul 2021, 4:20 PM
Srinath
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) { ... }
17th Jul 2021, 5:37 PM
Hatsy Rei
Hatsy Rei - avatar
+ 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.
18th Jul 2021, 1:53 AM
Hatsy Rei
Hatsy Rei - avatar
+ 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]?
19th Jul 2021, 3:09 PM
Hatsy Rei
Hatsy Rei - avatar
+ 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?
21st Jul 2021, 12:15 AM
Hatsy Rei
Hatsy Rei - avatar
+ 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
17th Jul 2021, 7:39 PM
Calvin Thomas
Calvin Thomas - avatar
+ 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.
19th Jul 2021, 3:36 PM
Srinath
+ 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?
19th Jul 2021, 3:39 PM
Srinath
+ 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.
21st Jul 2021, 3:14 PM
Calvin Thomas
Calvin Thomas - avatar