accessing a dynamic 2d array

Hey guys,

I have a question let's say I want access to the third pointer that examples the pointer to a pointer points to,how would I go about accessing this third pointer

below my code appears to be correct no errors or does not crash and prints the correct output,

but why cout << examples[6]->a << endl; examples is a pointer to a pointer so should that be invalid considering that examples is not an array of pointers,example points to an array of pointers( I probably already answered my own question above) but how is this legal? ig example points to an array of pointers example may or may not be contiguous in memory by this I mean example may not be directly the array of pointers so how is this legal?



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>

using namespace std;

class example{

  public:
      int a;
      int b;
      int c;

      example(){
         a = 10;
         b = 20;
         c = 30;
      }

      example(int a,int b,int c): a(a),b(b),c(c){}

};

example **examples;

void initExamples(){


  for(int i = 0; i < 10; i++){


      examples[i] = new example(i+10,i+20,i+5);
  }

}

int main()
{

     examples = new example*[10];
     initExamples();
     cout << examples[6]->a << endl;

}
1
2
3
4
5
6


example *examplesTwo = new example[10];

     cout << examplesTwo[5]->c << endl;


and above how come this is not legal??? and how do we access the fifth element in the array of examples ?

but also

1
2
3
4
5

example *examplesTwo = new example[10];

     cout << examplesTwo[0].c << endl;


why does this work?? considering that examplesTwo is a pointer shouldn't we have to use -> not . ????

thanks
Last edited on
Do you agree that:
1
2
3
4
int bar = 42; // bar is not a pointer
int* foo; // foo is a pointer
foo = &bar; // foo points to memory location of bar
std::cout << *foo; // access value at the location of bar, i.e. access value of bar 


If we are good so far, then lets do nothing:
1
2
3
4
*foo // access value == dereference pointer
*(foo) // the parentheses are just for clarity
*(foo+0) // address + 0 == address
foo[0] // the very same value access 

All four lines do exactly same. All four lines have an integer value.
The last just has a slightly different syntax.

int *gaz = new int[10];
The gaz does point to location of a int value, just like the foo before.

That integer value happens to be followed by other integer values in consecutive memory locations. If we add sizeof(int) to memory address of one of them, we do get address of the next integer value.

How much is pointer+1? It is the address stored in the pointer plus
sizeof(type in the pointers declaration).

You do have a pointer to type example object. When you do dereference that pointer, you get object of type example.

T * foo = new T[10];
foo+5 // address of the sixth T element in the array
*(foo+5) // the sixth T element in the array
foo[5] // the sixth T element in the array

1
2
3
4
5
// now the big reveal: T is example*
// an element in the array is a pointer
foo[5]->a // access member via pointer
*(foo[5]).a // dereference pointer and then access member of the object
foo[5][0].a // dereference pointer and then access member of the object 
If you understood how C strings worked, this should make sense:

char* c = "123"; is equivalent to char c[] = "123";

c[0] == char *(c+0) == char c == char*

Its mostly syntactic sugar, and that the elements are not pointers, the array is the only pointer (and this is also the same syntax for std::vector, which you should learn first before delving into pointers, to save you time in redundancy).

But when it comes down to 2d arrays, you should read the tutorial on this website because it gives a segment on how to treat a 1d array as a 2d array, because a jagged 2d array (aka **) are kinda weird when you think about how they work, and a 2d array created without new is equal to a 1d array with syntactic sugar. I generally recommend you to just create a class with a operator()(int x, int y) and just handle the 2d array internally as a 1d array, and either use a vector or make sure you handle memory with the ctor and dtor.
thanks guys that makes perfect sense,

one of those things that I know but for some reason took me off guard today,

thanks =)
char* c = "123"; is equivalent to char c[] = "123";

Not quite.

const char* foo = "123";
The foo is a pointer. It is initialized with the address of the first character of a constant string literal.

char bar[] = "123";
The bar is an array with four char elements. Those four elements are initialized with values '1', '2', '3', and '\0', respectively.

When you do use the bar:
1
2
3
4
char* foo = bar;
std::cout << bar;
char gaz = bar[2];
snafu( bar, 4);

the array decays into a pointer (temporarily).
Topic archived. No new replies allowed.