I am trying to understand the following 3 code statements involving pointers (through image diagrams). If you can explain it without images that would also work
1- myobj *ptra = new myobj();
2- myobj *ptrb = new myobj[2]();
3- myobj **ptrc = new *myobj();
Here is my understanding , please correct me if I am wrong. Also the addresses in the image are totally imaginary (I know they don't make sense). My major concerns of understanding are basically with statement 2 and statement 3.
Statement 1 : ptra (which is some address on the stack) points to an address on the heap
Statement 2: ptra (which is some address on the stack) points to one address which has 2 parts ? Is that correct ?

Your understanding is somewhat correct, though it seems like you mix too many things together and your diagram is missing details. Here is how I'd draw it for a few of the most simple cases...
Let's start from a simple case and take operator new out of the picture:
#include <cstdio>
struct myobj {
int v;
};
int main()
{
myobj obj[2];
obj[0].v = 1;
obj[1].v = 2;
myobj *ptra = &obj[0];
myobj *ptrb = &obj[1];
myobj **ptrc = &ptrb;
printf("obj size is: %lu\n", sizeof(myobj));
printf("pointer size: %lu\n", sizeof(void *));
printf("obj[0] address: %p\n", (void *)&obj[0]);
printf("obj[1] address: %p\n", (void *)&obj[1]);
printf("ptra address is %p, it points to %p\n", (void *)&ptra, (void *)ptra);
printf("ptrb address is %p, it points to %p\n", (void *)&ptrb, (void *)ptrb);
printf("ptrc address is %p, it points to %p\n", (void *)&ptrc, (void *)ptrc);
}
The above program will output something like this:
$ g++ -Wall -pedantic -o test ./test.cpp
$ ./test
obj size is: 4
pointer size: 8
obj[0] address: 0x7fff5b73dbc0
obj[1] address: 0x7fff5b73dbc4
ptra address is 0x7fff5b73dbb8, it points to 0x7fff5b73dbc0
ptrb address is 0x7fff5b73dbb0, it points to 0x7fff5b73dbc4
ptrc address is 0x7fff5b73dba8, it points to 0x7fff5b73dbb0
Which corresponds to the following simple layout in memory:

So what's different from your drawing? Addresses of pointers and objects. If the pointer itself is placed at address 0, then the next pointer cannot be placed at address 1 simply because a pointer itself takes more space, and so other data can only be placed at 0 + sizeof(void*) address. For objects, the next address is greater by at least the size of the object itself (i.e. sizeof(myobj)).
When dynamic allocation gets involved, the picture changes a bit. For example, when operator "new" is used to allocate objects like this:
myobj *ptra = new myobj();
myobj *ptrb = new myobj();
myobj **ptrc = &ptrb;
... you can think of a memory layout like this:

Now, a pointer to another pointer (**) is nothing but a pointer that points to the first of one or more pointers that point to object(s). Easy, right? Any you can have pointer to a pointer to a pointer... Anyway, with a dynamically allocated pointer to pointers, like this:
myobj *ptra = new myobj();
myobj *ptrb = new myobj();
myobj **ptrc = new myobj*[2];
ptrc[0] = ptra;
ptrc[1] = ptrb;
The memory layout could look like this:

By the way, you have an error in your line #3 here - myobj **ptrc = new *myobj();. It should be myobj **ptrc = new myobj*();.
To address your later questions, below is a diagram depicting the result of myobj *ptrb = new myobj[2](); expression where you have a pointer that points to two objects allocated dynamically. The pointer itself points to the first object out of two allocated:
![myobj *ptrb = new myobj[2]();](https://i.sstatic.net/nD4PW.png)
And one more time about pointers to pointers so that you can see the difference. Consider the following code:
struct myobj {
int v;
};
int main()
{
myobj *ptra = new myobj[2]();
myobj *ptrb = new myobj[4]();
myobj **ptrc = new myobj*[2];
ptrc[0] = ptra;
ptrc[1] = ptrb;
ptrc[0][0].v = 1;
ptrc[0][1].v = 2;
ptrc[1][0].v = 3;
ptrc[1][1].v = 4;
ptrc[1][2].v = 5;
ptrc[1][3].v = 6;
}
It will create the following layout:

As you can see, the stack contains three pointers (they are also objects) that are not dynamically allocated. This is a result of declaration:
myobj *ptra;
myobj *ptrb;
myobj **ptrc;
Then, three different things are allocated with "new":
myobj are allocated with expression new myobj[2](), the address to the first of those objects is stored in pointer ptra.myobj are allocated with expression new myobj[4](), the result of that expression is address of the first out of four objects, and it is stored in pointer "ptrb".new myobj*[2]. The result of that expression is an address of the first out of two pointers. That address is stored in variable ptrc.Now, those two allocated pointers (in "Block C") point "nowhere". So just for the sake of example we make them point to the same objects as ptra and ptrb are pointing by copying pointers "by value":
ptrc[0] = ptra;
ptrc[1] = ptrb;
That easy!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With