# Thread: Matrix on stack to int**... How?

1. ## Matrix on stack to int**... How?

Code:
```#include <iostream>
using namespace std;

int main() {
int matrix ;
for (unsigned int i = 0; i < 3; ++i) {
for (unsigned int j = 0; j < 3; ++j) {
matrix [i][j] = 0;
}
}
int** matrix_as_a_pointer = &(&(matrix));
return 0;
}```
Why is it that I can't do this? What's the best way to have an int** for a matrix on the stack? Thank you in advance. 2. Code:
`int** matrix_as_a_pointer = matrix;`
If you want to get a pointer to a location somwhere within the array, it would be:
Code:
`int** matrix_as_a_pointer = static_cast<int **>&matrix[y] [x];`
or
Code:
`int** matrix_as_a_pointer = &matrix[y] + x;`
or slightly more complex:
Code:
`int** matrix_as_a_pointer = matrix + y * 3 + x;` 3. Code:
`int** matrix_as_a_pointer = &(&(matrix));`
What is this??

Your rvalue is trying to get a pointer from a pointer to the first varible in the matrix.
If you want to get a pointer to the matrix just do like this:
Code:
`int ***matrix_as_a_pointer = &matrix;`
EDIT:
matsp - you posted while I was writing.

Don't do that.  4. Is that really supposed to work? I'm getting a segmentation fault on Ubuntu Linux by using:

Code:
```int** matrix_a_as_a_pointer = (int**)matrix_a; //If I omit the cast, the compiler produces a warning
printf("&#37;d\n, matrix_a_as_a_pointer");```
And yes, matrix_a is properly initialized. 5. Yes, of course. The double pointer will need to point to a pointer, which in turn points to the array content.

What are you ACTUALLY trying to do? In a bigger picture, that is.

--
Mats 6. I wish I could post the whole code here, but this is part of an assignment. Some of my colleagues would definitely resort to copying and pasting my code and calling it their own.

I can tell you this much: I want to have a char* with one of the matrix's lines. I created a function that does that whose prototype is
Code:
`char* getLine(int*** matrix, unsigned int line, unsigned int limit);`
So, if I want to get the matrix's line 0, i'd do
Code:
`getLine(&matrix, 0, 3);`
That is, if "matrix" is an int**, and if it has 3 columns.

However, using gdb, I found out this was giving me a segmentation fault when I tried to do, for instance, (*matrix) ("matrix" is now an int***, since it was passed to the function as such). I am unable to understand why. The matrix is properly initialized.

I'm sorry I can't provide more information. If this means you are unable to help me, then I understand I'm on my own. Nonetheless, thank you for your time. 7. No, I can help you, it's just that sometimes someone asks detailed questions, where the overall problem can be solved a differnet way.

So, essentially, you need to create another array:
Code:
```int *matrix_rows;
int **matrix_ptr;
for(i = 0; i < 3; i++)
matrix_rows[i] = &matrix[i];
matrix_ptr = matrix_rows;```
The above is just a sketch, it may need some "fixing", but I think it shows you the principle.

--
Mats 8. Well, the whole point of my question was to avoid copying things (in your case, pointers) to other locations. However, I'll have to resort to that if I run out of options anyway. 9. You are not copying things when you call the function - but a pointer to pointer must point to a valid memory address when you use ptr[y][x], because it's the same as *(*(ptr + y) + x). As you can see, there are two pointer dereferences - one for the (ptr + y), and then another for that address plus x.

The other option is to make it a pointer to int, and reference it with
Code:
`   matrix[x + y * hor_size];`
This is what the compiler does anyways, but it gets complicated when the indexes are complex (e.g matrix[y*2+3][x-5] is much easier to read than matrix[x-5 + (y*2+3) * hor_size];

--
Mats 10. Originally Posted by Mr_Miguel However, using gdb, I found out this was giving me a segmentation fault when I tried to do, for instance, (*matrix) ("matrix" is now an int***, since it was passed to the function as such). I am unable to understand why. The matrix is properly initialized.
A 2D (or more) stack array has a unique type that cannot be properly converted to a pointer type. As a result you cannot return a 2D stack array. Essentially the problem is that 2D stack arrays are handled as a 1D array, and the pointers to the beginning of each row are never stored, but rather are computed as needed.

The solutions are:
Return a 2d heap array (via pointer). This can be a problem because of memory management, in particular you should avoid having a function return a memory address it allocated.

Pass the 2d array as a parameter. Arrays are implicitly passed by reference. You can also create array references in your function body.

Return a vector of vectors of your type. This is usually the best way.

There are libraries that provide multidimensional array containers that are better than nested vectors because each row is required to be of the same length. You can use them. I believe boost has such a container. 11. Originally Posted by King Mir A 2D (or more) stack array has a unique type that cannot be properly converted to a pointer type. As a result you cannot return a 2D stack array. Essentially the problem is that 2D stack arrays are handled as a 1D array, and the pointers to the beginning of each row are never stored, but rather are computed as needed.

The solutions are:
Return a 2d heap array (via pointer). This can be a problem because of memory management, in particular you should avoid having a function return a memory address it allocated.

Pass the 2d array as a parameter. Arrays are implicitly passed by reference. You can also create array references in your function body.

Return a vector of vectors of your type. This is usually the best way.

There are libraries that provide multidimensional array containers that are better than nested vectors because each row is required to be of the same length. You can use them. I believe boost has such a container.
Well, technicaly, you can pass a stack array around using this method:
Code:
`func(int arr2d[], ...) ...`
The problem with any multidimensional arrays is that you do need to know the size of all dimensions besides the left-most one, because all C arrays are essentially 1D arrays, with a suitable calculation to achieve the location of the dimensions. The same applies when you allocate on the heap or if you create a global variable -it is only chunk of linear memory in every case.

--
Mats 12. I think I got it, guys. I think I have the cause of my problem. See the attachment.

Is it correct to conclude that A + 1 (i. e. ponteiro_matriz_a + 1) points to , when what I actually would want would be for it to point to ?

EDIT: Never mind. I get it now. My int** has the first element's address. ponteiro_matriz_a is equal to **ponteiro_matriz_a. Therefore, I dereference that pointer twice. The first time I dereference it, I get the matrix's first value, as an int*. On my case, that value is 1, or, in hexadecimal, 0x1. When I dereference it again, I attempt to access whatever it is at the address 0x1. But there's nothing there. That's why it's giving me a segmentation fault.

Note to self: never convert an integer 2D array to an int**. 13. Originally Posted by matsp Well, technicaly, you can pass a stack array around using this method:
Code:
`func(int arr2d[], ...) ...`
The problem with any multidimensional arrays is that you do need to know the size of all dimensions besides the left-most one, because all C arrays are essentially 1D arrays, with a suitable calculation to achieve the location of the dimensions. The same applies when you allocate on the heap or if you create a global variable -it is only chunk of linear memory in every case.

--
Mats
Yeah, that's what I meant by Pass the 2d array as a parameter. You can also do this to force the first parameter to be the same:
Code:
`void func(int (&arr2d));`
This also has the effect of making sizeof(array) be the actual size of the array. 14. Originally Posted by King Mir Code:
`void func(int (&arr2d));`

TO make the parameter a pointer to an array of ints, it should be:
Code:
`void func(int (*arr2d));`
Of course, functions defined like this will only work for that particular size array (which, I think, will not help whatever it is that the Original Poster is trying to accomplish).

D. 15. TO make the parameter a pointer to an array of ints, it should be:
King Mir wanted to demonstrate how to pass an array such that it does not decay to a pointer to its first element. It probably is not very useful since one needs to know the size of the array in order to write the function in the first place, in which case one could use the array size in the function directly.

I think that your example offers no advantage over King Mir's example, but is more complex. Either way, the array size can be directly used in the function, whether by hardcoding or through a constant since it is specific to the function and its array parameter.

It would be more flexible to pass the array such that it decays to a pointer to its first element, and then just provide the array size as another argument. Better yet, one could use a standard container such as std::vector. Popular pages Recent additions 