0

I have a pointer to a dynamically allocated 2-D array and am trying to print array values through dereferencing the pointer. Somehow, some of the array indices are showing garbage values even though I initialized them all to 1. Any insight into what I am doing wrong would be appreciated.

int main() {

int (*ptr)[4][4];
int** array;
array = new int*[4];

for (int i = 0; i < 4; i++)
{
    array[i] = new int[4];
}

ptr = (int(*)[4][4])(*array);


for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 4; j++)
    {
        array[i][j] = 1;

    }
}

for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 4; ++j)
    {
        cout<<"Val "<<*ptr[i][j]<<" And index "<<i<<" and "<<j<<endl;
    }
}
return 0; }

My output:

Val 1 And index 0 and 0
Val 0 And index 0 and 1
Val 1 And index 0 and 2
Val 0 And index 0 and 3
Val 1 And index 1 and 0
Val 0 And index 1 and 1
Val 1 And index 1 and 2
Val 0 And index 1 and 3
Val 543973718 And index 2 and 0
Val 1852383332 And index 2 and 1
Val 10 And index 2 and 2
Val 0 And index 2 and 3
Val 0 And index 3 and 0
Val 0 And index 3 and 1
Val 0 And index 3 and 2
Val 0 And index 3 and 3
Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
Curiosity
  • 105
  • 6
  • 3
    `ptr = (int(*)[4][4])(*array);` what do you think this does? – bolov Aug 25 '21 at 14:02
  • 1
    Your C-style cast gives it away. You are assigning `array` to `ptr`, but [they are not the same types](https://godbolt.org/z/G39h8d5fc). – Drew Dormann Aug 25 '21 at 14:03
  • 1
    Tldr: do not use C arrays; do not use explicit `new`; do not use owning raw pointers; do not use C casts. Use `std::vector` or `std::array`. – bolov Aug 25 '21 at 14:06
  • @bolov, I think it makes ptr point to array[0][0]. – Curiosity Aug 25 '21 at 14:06
  • 3
    *I think it makes ptr point to array[0][0].* I think it hides the bug that the compiler would otherwise warn you about. – Eljay Aug 25 '21 at 14:09
  • 1
    It doesn't. The C cast hides a type mismatch (basically it's an incompatibilitate `reinterpret_cast`) and the next uses of `ptr` invokes Undefined Behavior. – bolov Aug 25 '21 at 14:11
  • Did you add the C-style cast because you saw a compiler error? – Drew Dormann Aug 25 '21 at 14:12
  • `ptr` is a pointer to an array. `array` is a pointer to a pointer. Related reading - [Is an array a pointer?](https://stackoverflow.com/questions/1641957/is-an-array-name-a-pointer) – Drew Dormann Aug 25 '21 at 14:15
  • I see. Need to read up more on this. – Curiosity Aug 25 '21 at 14:22
  • Also, `*ptr[i][j]` means `*(ptr[i][j])` - that is, `ptr[i][j][0]` - not `(*ptr)[i][j]`, so it would be wrong even if `ptr` really did point to an `int[4][4]`. – molbdnilo Aug 25 '21 at 14:31

1 Answers1

0

Let's look at your basic code.

int (*ptr)[4][4];
int** array;
array = new int*[4];

for (int i = 0; i < 4; i++)
{
    array[i] = new int[4];
}

ptr = (int(*)[4][4])(*array);

This is the part that matters. Let's look at what array is.

Array is a pointer to pointers. While you're doing this in a very C-style fashion, what you're doing is okay. You are allocating space for 4 pointers, and then each of those pointers gets space for 4 ints. So this gives you a 4x4 array (sort of).

But what is ptr?

int (*ptr)[4][4];

Ptr is a pointer to a 4x4 array of ints. That is NOT what array is. Array is a pointer to 4 pointers, and each of those points to space for 4 ints. They are NOT THE SAME.

They are stored differently. Array has 5 pointers total: itself plus the 4 new pointers.

ptr expects one pointer (itself) to 16 ints that are contiguous in memory, with no other points.

And that's why it's not working how you expect.


You're also making this too complicated, but maybe there are reasons for that. The C++ way is to dramatically reduce the number of new/delete. There are containers in the STL you can use.

Or you can just do this:

int array[4][4];

No pointers involved. But maybe you want it to be variable for a reason.

Joseph Larson
  • 8,530
  • 1
  • 19
  • 36
  • Thanks. This makes sense. Once I create the dynamic 2-D array pointed to by array (the double pointer), is there any correct/accepted way for ptr to be pointed to that array? – Curiosity Aug 25 '21 at 16:42
  • @Curiosity Remember when you're happy with an answer to mark one of them as the best. This marks the question as answered and rewards the people who take the time to try to help. – Joseph Larson Aug 26 '21 at 17:03