How to assign a multidimensional array to a temporary variable?

I want to assign a statically distributed multidimensional array to a temporary variable. Consider the following example:

void foo(int b[3][2]) { b[1][1] = 1; // no segmentation fault } int main() { int a[3][2] = {{1, 2}, {11, 12}, {21, 22}}; foo(a); int** c; c = (int**)&a; c[1][1] = 1; // segmentation fault on execution int* d[3]; d[0] = (int*)&(a[0]); d[1] = (int*)&(a[1]); d[2] = (int*)&(a[2]); d[1][1] = 1; // no segmentation fault return 0; } 

Basically, I want to do what the compiler does with the b parameter foo() . But the only working solution I could come up with is d . No less complicated way?

+6
source share
6 answers

cdecl ( man page ) is your friend:

 cdecl> explain int b[3][2] declare b as array 3 of array 2 of int cdecl> declare b as pointer to array 2 of int int (*b)[2] 

So try the following:

 void foo(int b[3][2]) { b[1][1] = 1; // no segmentation fault } int main() { int a[3][2] = {{1, 2}, {11, 12}, {21, 22}}; foo(a); int (*b)[2] = a; b[1][1] = 1; return 0; } 
+11
source

int[3][2] and int** are incompatible types. You cannot throw each other.

Try the following:

 int (*c)[2]; c = a; //no need to cast c[1][1] = 1; //ok 

Or you could do this (declaration as well as initialization):

 int (*c)[2] = a; //no need to cast c[1][1] = 1; //ok 

Rule of thumb:

  • Do not use c-style cast in C ++. Use C ++ style. If you used the C ++ style, the compiler would tell you about the problem much earlier ( ideone ) (there is no need to run the code for see the problem):

     prog.cpp:5: error: invalid static_cast from type 'int (*)[3][2]' to type 'int**' 

    But a C-style listing compiles perfectly ( ideone ), as you already know.

  • And whenever you use cast, even a C ++ style cast, your first doubt should be the application itself if the program does not work properly.

+9
source

As you now know, from other answers, type a is not really equivalent to int** - it jsut splits into this (when it is returned / passed by value).

 int (*b)[2] = a; // would solve that 

There are more C ++ features:

 typedef std::array<std::array<int, 2>, 3> M23; void foo(M23& b) { b[1][1] = 1; } int main() { M23 a = {{1, 2}, {11, 12}, {21, 22}}; foo(a); M23 d = a; d[1][1] = 1; } 
+5
source

If you use a fairly modern compiler that supports sufficient parts of the C ++ 11 standard, you can use auto :

 int a[3][2] = ...; auto &b = a; b[1][1] = 1; // a[1][1] will be set 

Of course, both a and b must be defined in the same scope as for the job. You cannot have an auto parameter in a function, for example (what the templates are for.)

+2
source

Do not type explicitly, so try writing

  c = &a; 

Then the GCC compiler (using gcc -Wall -g bidim.c -o bidim to compile) gives the correct warning:

 bidim.c:13:7: warning: assignment from incompatible pointer type [enabled by default] 

And then you should understand that a 2D matrix is โ€‹โ€‹not implemented as an array of pointers to 1D arrays.

+1
source

The first thing that comes to my mind is the use of typedef and reference, for example

 typedef int thing_t[3][2]; thing_t& e = a; e[1][1] = 1; 

With pointers

 int (*f)[2] = a; f[1][1] = 1; 

Another possibility is encapsulation in a struct .

0
source

Source: https://habr.com/ru/post/902004/


All Articles