Reputation: 73
I'm trying to have three levels of pointer indirection with an additional pointer pointing to level two of the indirection. This is for a class, and I'm having some real issues. This is what I'm doing.
int ***s = new int **[row];
*s = new int *[row];
**s = new int[row];
Now if these where just int and not arrays I could do,
***s = 1;
To store it into the yellow square on my picture, but I don't know how to access the array elements, I have tried a few things and it either crashes or will not compile. Any help, even pointing me in the right direction would be very useful. Thank you.
Upvotes: 1
Views: 782
Reputation: 32994
You've created something like this (assume row
is 2 and type T
):
T*** +-----+ | | +--/--+ / / T** +--/--+-----+ | | | +-----+--+--+ -/ | --/ T* | +--/--+-----+ +-+---+-----+ | | | | | | +-----+-----+ +--+--+-----+ ----/ -/ | \--- -----/ --/ T | \-- +--/--+-----+ +--/--+-----+ +--+--+-----+ +--\--+-----+ | | | | X | | | | | | | | +-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
Every node would point to the next level's first node. Dereferencing every level would give the level next but you've to also take care of the index of the element in the array you want to reach. This, I see, isn't done in your code. For scalars you dereference using *
while for arrays the array index syntax does dereferencing too apart from choosing the right element. *
on arrays would just get you the first element always.
To access X
in the above figure you'd do
T** v = u[0];
T* w = v[1];
T x = w[0];
// shorthand for above
x = u[0][1][0];
To just have an array at the last level, you should be doing this
int*** p = new int**;
*p = new int*;
**p = new int[row];
This would just give you █ → █ → █ → █ █ █ …, where p
itself (the first box) is an automatic variable (usually stored in the stack space) and rest comes from the freestore (usually living in the heap).
Upvotes: 2
Reputation: 85887
Let's say row = 3
for this example.
int ***s;
// s=[?]
// s is an uninitialized variable.
s = new int **[row];
// s[*] -> [?]
// [?]
// [?]
// s points to the first element of an array of size 3.
// The elements are uninitialized.
*s = new int *[row];
// s=[*] -> [*] -> [?]
// [?] [?]
// [?] [?]
// We've initialized s[0]. It points to another array of size 3.
// All elements of that array are also uninitialized, along with s[1] and s[2].
**s = new int[row];
// s=[*] -> [*] -> [*] -> [?]
// [?] [?] [?]
// [?] [?] [?]
// More of the same. s[0][0] is initialized.
// This last array contains uninitialized ints, not pointers.
***s = 1;
// s=[*] -> [*] -> [*] -> [1]
// [?] [?] [?]
// [?] [?] [?]
// We traverse three levels of pointers (->) and store 1 in the cell.
All of this should compile and work fine (as long as you don't access any of the uninitialized elements).
s + 1
points to the second element of the first array.
// s=[*] -> [*] -> [*] -> [1]
// s + 1 -> [?] [?] [?]
// [?] [?] [?]
*(s + 1)
refers to the cell [?]
pointed to by s + 1
in the diagram above. This cell is uninitialized.
**(s + 1)
tries to dereference a garbage pointer, which is invalid (and often crashes).
Upvotes: 1