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();
Run Code Online (Sandbox Code Playgroud)
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 ?

小智 7
你的理解有点正确,虽然看起来你把很多东西混在一起,你的图表缺少细节.以下是我为一些最简单的案例绘制它的方法......
让我们从一个简单的案例开始,让运算符new脱离图片:
#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);
}
Run Code Online (Sandbox Code Playgroud)
上面的程序将输出如下内容:
$ 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
Run Code Online (Sandbox Code Playgroud)
这对应于内存中的以下简单布局:

那么你的绘画有什么不同?指针和对象的地址.如果指针本身位于地址0,则下一个指针不能仅仅因为指针本身占用更多空间而放置在地址1,因此其他数据只能放在0 + sizeof(void*)地址处.对于对象,下一个地址至少大于对象本身的大小(即sizeof(myobj)).
当涉及动态分配时,图像会发生一些变化.例如,当运算符"new"用于分配这样的对象时:
myobj *ptra = new myobj();
myobj *ptrb = new myobj();
myobj **ptrc = &ptrb;
Run Code Online (Sandbox Code Playgroud)
...你可以想到这样的内存布局:

现在,指向另一个指针(**)的指针只不过是指向一个或多个指向对象的指针中的第一个的指针.容易,对吗?任何你可以指向一个指向指针的指针...无论如何,动态分配指针指针,如下所示:
myobj *ptra = new myobj();
myobj *ptrb = new myobj();
myobj **ptrc = new myobj*[2];
ptrc[0] = ptra;
ptrc[1] = ptrb;
Run Code Online (Sandbox Code Playgroud)
内存布局可能如下所示:

顺便说一下,你的第3行出现错误 - myobj **ptrc = new *myobj();.它应该是myobj **ptrc = new myobj*();.
为了解决您以后的问题,下面是一个描述myobj *ptrb = new myobj[2]();表达式结果的图表,其中有一个指向动态分配的两个对象的指针.指针本身指向分配的两个中的第一个对象:
![myobj*ptrb = new myobj [2]();](https://i.stack.imgur.com/nD4PW.png)
还有一次关于指针的指针,以便你可以看到差异.请考虑以下代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
它将创建以下布局:

如您所见,堆栈包含三个未动态分配的指针(它们也是对象).这是声明的结果:
myobj *ptra;
myobj *ptrb;
myobj **ptrc;
Run Code Online (Sandbox Code Playgroud)
然后,用"new"分配三个不同的东西:
myobj分配有表达式new myobj[2](),第一个对象的地址存储在指针中ptra.myobj分配有表达式new myobj[4](),该表达式的结果是四个对象中第一个的地址,并存储在指针"ptrb"中.new myobj*[2].该表达式的结果是两个指针中第一个的地址.该地址存储在变量中ptrc.现在,这两个分配的指针(在"块C"中)指向"无处".因此,仅仅为了示例,我们使它们指向相同的对象,ptra并ptrb通过"按值"复制指针来指向:
ptrc[0] = ptra;
ptrc[1] = ptrb;
Run Code Online (Sandbox Code Playgroud)
那简单!