Putting [][] in ** [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Passing two-dimensional array via pointer
int table[20][20];
int** table1 = table;
int a;
table[0][0] = 4;
a = table1[0][0];
the last line gives me Access violation, and i dont get it ..
thanks in advance!

The short answer is that a pointer to a pointer is not the same as an array of arrays.

You can't make a int ** from a two dimensional int array in one assignment. First, you need to allocate the correct number of pointers:
table1 = malloc(sizeof(int*) * 20);
Then you can use a loop to fill in your next level pointers:
for(int i = 0; i < 20; i++)
table1[i] = table[i];
The reason is that pointer to pointer is ONE memory location that holds an address. When you make the first allocation, that makes that pointer point to 20 int pointers. We then assign each of those pointers the first address of each row in the original table. Now, when we use a = table1[0][0], the compiler will go fetch table1[0] - so the first pointer in the array we set up in the loop. This points to table[0] row, so we fetch the [0] element from that, and get the 4 that was stuffed in there [of course, any other number index would also get four, so it's hard to show that it works right in this case).
In the table[y][x] case, the compiler will take the address of table, add y * 20 * sizeof(int) to it, and then add x * sizeof(int). Which gives us a nice place in the "square" lump of memory that "table" is.
(Again, typing too much, two more answers since I started writing this)

C compilers are just too forgiving:
int** table1 = table;
c.c: In function ‘main’:
c.c:3:17: warning: initialization from incompatible pointer type [enabled by default]
If we feed it incorrect code, the compiler complains, and we ignore the complaint and then get some strange outcome, should we wonder?
Anyway, table1 doesn't point to a pointer to int, and the way it's going to crash is a matter of implementation (alignment, segmentation etc.)

Although table1[1] is of type pointer, there are no pointers anywhere in table.

Ask yourself: Given a pointer, and being told to access item 3, 4 - how should the compiler know how large the first dimension of your two-dimensional array is, in order to skip the right amount of items?
Correct: Not at all.

Given
int table[20][20];
table is compatible with int*, not int**.
This should compile and be able to access table1 from table1[0] to table1[399]:
int* table1 = table;

Related

How do I de-reference a pointer that is inside of an array using its index?

I am working on a stacks assignment in which we are creating a stack of pointers to structs called Data. Our professor is trying to help us develop good habits in regards to security in designing a program, which is why we have a stack of pointers to structs rather than a stack of the structs themselves.
I know that typically when de-referencing a pointer, you do it with an asterisk. Example:
int x = 5;
int* xptr = &x;
cout << *xptr << endl;
My understanding is that the above code would create a var x with the value 5, then a pointer that store the address of the var x, and then by printing *xptr, you are de-referencing the pointer, which causes the printed output to be the value of x (5). If I'm incorrect anywhere so far, let me know.
So now onto the stack class, my professor created the .h file for us and we have these attributes:
int top; // this is your top index
Data *stack[STACK_SIZE];
My understanding of the stack is that we have an array of pointers to Data structs (as indicated by the * prior to the name "stack") and the stack is literally named "stack". My question is: when I need to pop a Data struct off (I'm calling it popData) and I want to assign its value, I know that I can't just do popValue = stack[top] because popValue is of type Data, which can't receive an assignment of a pointer.
I was thinking I could do this:
Data popData;
*Data popDataPtr;
popDataPtr = stack[top];
popData = *popPtr;
I am thinking that logically this would work, but I was wondering if there is syntax for de-referencing the ptr and assigning it in the same line. I'm thinking either:
popData = *stack[top];
or
popData = stack[*top];
But I'm not sure what's correct. I can't seem to find an example online of this. Thanks in advance to anyone who can help.
I would recommend trying it next time by yourself to see which of your examples would work.
You can have the assignment in one line, and I would recommend also adding parentheses in complex expressions like this, so you don't have to memorize operator precedence:
Data popData = *(stack[top]);
Small comment regarding your other code, this will not compile:
*Data popDataPtr;
The syntax for a pointer to a Data is no different from a pointer to an int, which you had before:
int* xptr = &x;
So to make the code from your example work, you actually need
Data* popDataPtr;
There is a great rule of thumb in C++: read the declarations from right to left, for example:
Data * const ptr1; // ptr1 is a constant pointer to a Data
const Data * ptr2; // ptr2 is a pointer to Data which is const (or just to a constant Data)
Data * arr1[]; // arr1 is an array of pointers to Data.
popData = *stack[top]; // this will do the trick
Here you are accessing the pointer that you want and you are then dereferencing that pointer and storing the data pointed to in popData

typecasting int [n][m] to int ** gives segmentation fault [duplicate]

This question already has answers here:
Why can't we use double pointer to represent two dimensional arrays?
(6 answers)
Closed 6 years ago.
int main()
{
matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
int **ptr = (int**)matrix;
printf("%d%d",**matrix,*ptr);
}
But when a 2-d array is passed as a parameter it is typecasted into (*matrix)[2] ..
what type does the compiler store this array as... is it storing as a 2-d array or a double pointer or an pointer to an array .. If it is storing as an array how does it interprets differently at different situations like above. Please help me understand.
Is 2d array a double pointer?
No. This line of your program is incorrect:
int **ptr = (int**)matrix;
This answer deals with the same topic
If you want concrete image how multidimensional arrays are implemented:
The rules for multidimensional arrays are not different from those for ordinary arrays, just substitute the "inner" array type as element type. The array items are stored in memory directly after each other:
matrix: 11 22 33 99 44 55 66 110
----------- the first element of matrix
------------ the second element of matrix
Therefore, to address element matrix[x][y], you take the base address of matrix + x*4 + y (4 is the inner array size).
When arrays are passed to functions, they decay to pointers to their first element. As you noticed, this would be int (*)[4]. The 4 in the type would then tell the compiler the size of the inner type, which is why it works. When doing pointer arithmetic on a similar pointer, the compiler adds multiples of the element size, so for matrix_ptr[x][y], you get matrix_ptr + x*4 + y, which is exactly the same as above.
The cast ptr=(int**)matrix is therefore incorrect. For once, *ptr would mean a pointer value stored at address of matrix, but there isn't any. Secondly, There isn't a pointer to matrix[1] anywhere in the memory of the program.
Note: the calculations in this post assume sizeof(int)==1, to avoid unnecessary complexity.
No. A multidimensional array is a single block of memory. The size of the block is the product of the dimensions multiplied by the size of the type of the elements, and indexing in each pair of brackets offsets into the array by the product of the dimensions for the remaining dimensions. So..
int arr[5][3][2];
is an array that holds 30 ints. arr[0][0][0] gives the first, arr[1][0][0] gives the seventh (offsets by 3 * 2). arr[0][1][0] gives the third (offsets by 2).
The pointers the array decays to will depend on the level; arr decays to a pointer to a 3x2 int array, arr[0] decays to a pointer to a 2 element int array, and arr[0][0] decays to a pointer to int.
However, you can also have an array of pointers, and treat it as a multidimensional array -- but it requires some extra setup, because you have to set each pointer to its array. Additionally, you lose the information about the sizes of the arrays within the array (sizeof would give the size of the pointer). On the other hand, you gain the ability to have differently sized sub-arrays and to change where the pointers point, which is useful if they need to be resized or rearranged. An array of pointers like this can be indexed like a multidimensional array, even though it's allocated and arranged differently and sizeof won't always behave the same way with it. A statically allocated example of this setup would be:
int *arr[3];
int aa[2] = { 10, 11 },
ab[2] = { 12, 13 },
ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;
After the above, arr[1][0] is 12. But instead of giving the int found at 1 * 2 * sizeof(int) bytes past the start address of the array arr, it gives the int found at 0 * sizeof(int) bytes past the address pointed to by arr[1]. Also, sizeof(arr[0]) is equivalent to sizeof(int *) instead of sizeof(int) * 2.
In C, there's nothing special you need to know to understand multi-dimensional arrays. They work exactly the same way as if they were never specifically mentioned. All you need to know is that you can create an array of any type, including an array.
So when you see:
int matrix[2][4];
Just think, "matrix is an array of 2 things -- those things are arrays of 4 integers". All the normal rules for arrays apply. For example, matrix can easily decay into a pointer to its first member, just like any other array, which in this case is an array of four integers. (Which can, of course, itself decay.)
If you can use the stack for that data (small volume) then you usually define the matrix:
int matrix[X][Y]
When you want to allocate it in the heap (large volume), the you usually define a:
int** matrix = NULL;
and then allocate the two dimensions with malloc/calloc.
You can treat the 2d array as int** but that is not a good practice since it makes the code less readable. Other then that
**matrix == matrix[0][0] is true

Pointer to int array, passing and using it from another method

I haven't cemented my learning of C++ arrays and have forgotten how to do this properly. I've done it with char array before but its not working as well for int array.
I declare a new blank int array:
int myIntArray[10];
So this should be an array of nulls for the moment correct?
Then I assign a pointer to this array:
int *pMyArray = myIntArray
Hopefully thats correct to there.
Then I pass this to another method elsewhere:
anotherMethod(pMyArray)
where I want to assign this pointer to a local variable (this is where I'm really not sure):
anotherMethod(int *pMyArray){
int myLocalArray[];
myLocalArray[0] = *pMyArray;
}
I'm not getting any compilation errors but I'm not sure this is right on a few fronts. Any and all help and advice appreciated with this.
Edit:
I should have said what I am trying to do.
Very simple really, I'd just like to modify a local array from another method.
So I have:
Method 1 would contain:
int myArray1[10] = {0};
Method 2 would be passed the pointer to myArray:
Then some code to modify the variables in the array myArray.
int myIntArray[10];
This is an uninitialized array. It doesn't necessarily contain 0's.
int *pMyArray = myIntArray
Okay, pMyArray points to the first element in myIntArray.
anotherMethod(int *pMyArray){
int myLocalArray[10];
myLocalArray[0] = *pMyArray;
}
This doesn't assign your pointer to anything, it assigns the first value of the local array to the int pointed to by pMyArray, which, remember, was uninitialized. I added the 10 there because you can't have an array of unknown size in C++.
To modify what pMyArray points to, you need to pass it by reference:
anotherMethod(int *& pMyArray)
Also, if you assign it to some values in automatic storage, it will result in undefined behavior, as that memory is no longer valid when the function exits.
int myIntArray[10];
So this should be an array of nulls for the moment correct?
No, this is an array of 10 integers containing values depending on the storage specification.
If created locally, it has random garbage values.
If created globally it is value initialized which is zero initialized for POD.
Besides that your method just assigns the local array with the first vale of the array you pass.
What are you trying to do exactly? I am not sure.
int myIntArray[10];
So this should be an array of nulls for the moment correct?
Not correct, it is an array of 10 uninitialized ints.
int *pMyArray = myIntArray
Hopefully thats correct to there.
Not quite correct, pMyArray is a pointer to the 1st element, myIntArray[0].
where I want to assign this pointer to a local variable (this is where
I'm really not sure):
If you really need to assign the pointer, you have to use this code
int *p_myLocalArray;
p_myLocalArray = pMyArray;
There are a few mistakes here.
First, array of zeros (not nulls) is achieved by using the initializer syntax:
int myIntArray[10] = {0};
Second, int myLocalArray[]; has a size of 0. And even if it did have a size of, say, 10, writing myLocalArray[0] = *pMyArray; will assign the first int from pMyArray into mLocalArray, which is not what you meant.
If you want to assign a pointer of the array, then simply:
int *myLocalPointer;
myLocalPointer = pMyArray;
If you want a local copy of the array, you will need to copy it locally, and for that you also need the size and dynamic allocation:
void anotherMethod(int *pMyArray, int size){
int *myLocalArray = (int *)malloc(size * sizeof(int));
memcpy(myLocalArray, pMyArray, size * sizeof(int));
...
free(myLocalArray);
}

Syntax for pointer to portion of multi-dimensional statically-allocated array

Okay, I have a multi-dimensional array which is statically-allocated. I'd very much like to get a pointer to a portion of it and use that pointer to access the rest of it. Basically, I'd like to be able to do something like this:
#include <stdio.h>
#include <string.h>
#define DIM1 4
#define DIM2 4
#define DIM3 8
#define DIM4 64
static char theArray[DIM1][DIM2][DIM3][DIM4] = {0};
int main()
{
strcpy(theArray[0][0][0], "hello world");
char** ptr = theArray[0][0];
printf("%s\n", ptr[0]);
return 0;
}s
This code results in this error using gcc:
t.c: In function ‘main’:
t.c:17: warning: initialization from incompatible pointer type
char** is apparently not the correct type to use here. I assume it's because statically-allocated arrays are created as a single block in memory while dynamically allocated ones are separated in memory, with each dimension having a pointer to the next one.
However, as you likely noticed, the number of dimensions here is painfully large, and I'm obviously going to need to use actual variables to index the array rather than the nice, slim character 0, so it's going to get painfully long to index the array in actual code. I'd very much like to have a pointer into the array to use so that accessing the array is much less painful. But I can't figure out the correct syntax - if there even is any. So, any help would be appreciated. Thanks.
theArray[0][0] gets rid of the first two dimensions, so you have something of type char [DIM3][DIM4]. The first dimension will drop out when the array decays to a pointer, so the declaration you want is:
char (*ptr)[DIM4] = theArray[0][0];
For what it's worth, gcc also displays a warning for your array declaration: "warning: missing braces around initializer". Static variables and global variables will automatically be initialized to 0, so you can fix the warning by getting rid of the initializer:
static char theArray[DIM1][DIM2][DIM3][DIM4];
Given a declaration
T arr[J][K][L][M];
the following all hold:
Expression Type Decays to
---------- ---- ---------
arr T [J][K][L][M] T (*)[K][L][M]
&arr T (*)[J][K][L][M]
arr[j] T [K][L][M] T (*)[L][M]
&arr[j] T (*)[K][L][M]
arr[j][k] T [L][M] T (*)[M];
&arr[j][k] T (*)[L][M]
arr[j][k][l] T [M] T *
&arr[j][k][l] T (*)[M]
So, in your case, the type of ptr needs to be char (*)[DIM4].
If you are using Visual Studio, a nice way to find out the type of the expression is to use typeid.
cout << typeid(&theArray[0][0]).name();
which prints
char (*)[8][64]
But note that output of typeid().name() is an implementation specific behavior and as such can not be relied upon. But VS happens to be nice in this regards by printing a more meaningful name
Does not matter that it is static, your types don't match
Why a double pointer can't be used as a 2D array?
This is a good example, although the compiler may not complain,
it is wrong to declare: "int **mat" and then use "mat" as a 2D array.
These are two very different data-types and using them you access
different locations in memory. On a good machine (e.g. VAX/VMS) this
mistake aborts the program with a "memory access violation" error.
This mistake is common because it is easy to forget that the decay
convention mustn't be applied recursively (more than once) to the
same array, so a 2D array is NOT equivalent to a double pointer.
A "pointer to pointer of T" can't serve as a "2D array of T".
The 2D array is "equivalent" to a "pointer to row of T", and this
is very different from "pointer to pointer of T".
When a double pointer that points to the first element of an array,
is used with subscript notation "ptr[0][0]", it is fully dereferenced
two times (see rule #5). After two full dereferencings the resulting
object will have an address equal to whatever value was found INSIDE
the first element of the array. Since the first element contains
our data, we would have wild memory accesses.
...
etc....
http://www.ibiblio.org/pub/languages/fortran/append-c.html

how to represent int * as array in totalview?

How do I 'dive' an int * which points to a dynamically allocated array of integers and represent it as a fixed int[] array? Put otherwise, if I dive an int * it shows the address and the int pointed to, but instead I would like to see the array of all of the integers.
I noticed the TotalView tag on this question. Are you asking how to see the values in your array in totalview? If so then the answer is pretty easy.
Lets say you have a pointer p which is of type int * and you have it currently pointing towards an array with 10 integers.
Step 1. Dive on the pointer. That's accomplished by double clicking, clicking the middle mouse button, or using the dive option on the context menu -- all after having placed the mouse cursor on the variable int he source code pane or the stack frame pane.
This will bring up a new window that will say
Expression: p
Address: 0xbfaa1234
Type: int *
and down in the data area will say something like
0x08059199 -> 0x000001a5 (412)
This window is showing you the pointer itself, the address listed is the address of the pointer. The value (0x08059199 in the example above) is the actual value that the pointer has. Everything to the right of the arrow is just a "hint" telling you want it points to.
Step 2. Dive on the pointer again. Repeat the double click or middle mouse button, this time on the data value in the variable window. (So you are double clicking where it says 0x08059199).
This will effectively "dereference" the pointer. Now the window is focused not on pointer itself but the thing that the pointer pointed to. Notice that the address box now contains 0x08059199 which was the value before.
expression: *(((int *) p))
Address: 0x08059199
Type: int
and down in the data area it will say something like
0x000001a5 (412)
Step 3. Cast the data window to the type you want. Just click in the type field and change it to say int[10]. Then hit return.
This tells the debugger that 0x08059199 is the beginning of an array of 10 integers.
The window will grow two new fields: Slice and Filter. You can leave those alone for now, but they can be useful later.
The data area will now show two columns "field" and "value" and 10 rows.
The field column will be the index in the array [0] - [9] and the value column will tell you what data you have in each array location.
Other tips:
In more complicated data structures you can may want to dive on individual elements (which might also be pointers, diving will dereference them as well)
You can always cast to different types or lengths to look at data "as if it was" whatever
You can edit the actual data values by clicking on the value column and editing what you find there. This is useful when you want to provoke specific mis-behavior from your application
You can always undo diving operations with the "<" icon in the upper right hand corner of the variable window.
There are some online videos that you might find helpful at
http://www.roguewave.com/products/totalview/resources/videos.aspx
in particular there is one labeled "getting started with TotalView".
Don't hesitate to contact us at Rogue Wave Software for TotalView usage tips!
support at roguewave dot com is a good address for that.
Chris Gottbrath
(Chris dot Gottbrath at roguewave dot com)
TotalView Product Manager at Rogue Wave Software
It's not very hard, but i forgot how it exactly works. I found you a page which explains it tho ;). I think to point and array with ints called for example test you should get it using &test.
Just check this page out:
http://www.cplusplus.com/doc/tutorial/pointers/
You can't meaningfully do this without knowing exactly how many ints are in the array.
If you have an int *p that points to the first element in a contiguous int data, either dynamically allocated, or a static array, you can index it as if it were an array:
int *data = malloc(3 * sizeof *data);
int *p;
/* malloc error detection omitted for brevity */
data[0] = 1;
data[1] = 2;
data[3] = 42;
p = data;
assert(p[0] == 1);
assert(p[1] == 2);
assert(p[2] == 42);
You have to know the size of the valid data you are accessing this way.
So, let's say I have data as above, and want to write a function to print it. It won't do to declare the function like this:
void print_array(int *data);
because when you call print_array(data);, the function doesn't know the number of elements to print.
You could define your print_array() like:
void print_array(int *data, size_t n);
where n denotes the number of valid elements pointed to by data, that the caller has to supply. Or you could decide that every "array" will end with a sentinel value, a value that is used only at the end of the data, and is not useful value otherwise:
data[2] = 0; /* data[0] and data[1] are useful, valid values
and data[2] is 0 to signify the end of the data */
Then you can declare your print_array() as:
void print_array(int *data);
and keep indexing into data in the function definition till you hit a sentinel:
void print_array(int *data)
{
size_t i;
for (i=0; data[i] != 0; ++i)
printf("%d\n", data[i]);
}
So, to answer your question, you can already treat a pointer to a valid dynamically allocated data as an array. You have to remember the size of the allocated data of course, which you would need to do in a regular array too.