[英]stuck on copying memory managed by a double pointer to a two-dimensional array
代码如下:
#include <iostream>
using std::cout;
int main(int argc, char ** argv)
{
int** p;
int a[2][3]={{-1,-1,-1},
{-1,-1,-1}};
int k=1;
p = new int *[2];
for(int i=0;i<2;i++) {
p[i] = new int[3];
for(int j=0;j<3;j++) {
p[i][j] = k++;
}
}
memcpy(a,p,2 * 3 * sizeof(int));
for(int i=0;i<2;i++){
for(int j=0;j<3;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
delete [] p;
return 0;
}
运行后得到意想不到的结果:
26573888 0 26573920
0 0 0
我认为它复制了地址而不是值,所以我更改了memcpy(a,p,2 * 3 * sizeof(int));
至
memcpy(a,p[0],2 * 3 * sizeof(int));
终端打印出来:
1 2 3
0 0 0
如何理解上述结果? 谁能帮我吗?
猜测
p[0][2]
和p[1][0]
的地址不连续?
你在混合东西...
这个另一个问题(尤其是公认的答案)很好地解释了它。 您有一个 static 二维数组和一个int**
。
这两个看起来一样,但不是。 编译器知道哪个是哪个,所以一个是连续布局的,另一个不是。
您甚至可以在代码中看到这一点。 一旦你写
int a[2][3]={{-1,-1,-1},
{-1,-1,-1}};
其中 object 是 memory 的一块,用a
表示
但是然后你写
p = new int *[2];
for(int i=0;i<2;i++) {
p[i] = new int[3];
for(int j=0;j<3;j++) {
p[i][j] = k++;
}
}
你有一个 object p
。 然后使用p[i] = new int[3]
行打开 go 并制作 2 个单独的int[3]
对象。 这些谎言谁知道在哪里。 并且它们的地址被分配给指针p[i]
。
TL;DR: int[2][3]
类型与int**
有着根本的不同,而且它们之间的互操作性并不简单。
您必须每行执行一次memcpy
才能获得预期结果:
memcpy(a[0], p[0], 3 * sizeof(int));
memcpy(a[1], p[1], 3 * sizeof(int));
原因是行不连续。
住在神螺栓上
p[0]
的类型是什么?
int*
a[0]
的类型是什么?
int[3]
a[0]
在适当的上下文中衰减为一个指针(例如,当作为参数传递给 function 时),但它本身并不是一个指针,与p[0]
完全相反,它从一开始就是正确的。 如果您例如比较两者的大小( sizeof(a[0])
给出三个整数的大小, sizeof(p[0])
给出指针的大小),您会注意到差异。
数组成员总是一个接一个地连续放置,所以对于a
,有两个 arrays 一个接一个地放置:
a: { { -1, -1, -1 }, {-1, -1, -1 } }
对于p
实际上完全一样,每个成员一个接一个连续地跟随; 只是,这一次,成员是真正的指针(即内存中的某个地址)。 还有其他 arrays,但这些(必然)放在别处:
p: { <pointer>, <pointer> }
| |
V |
{ 1, 2, 3} |
V
{ 4, 5, 6}
所以总而言之,你的猜测是正确的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.