坚持将双指针管理的内存复制到二维数组
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]
的猜测
地址不连续?
p[0]
的类型是什么?
int*
a[0]
的类型是什么?
int[3]
a[0]
在适当的上下文中衰减到指针(例如,当作为参数传递给函数时(,但它本身就不是指针,与从一开始就正确的p[0]
完全相反。例如,如果您比较两者的大小(sizeof(a[0])
给出三个整数的大小,sizeof(p[0])
给出指针的大小(,您会注意到差异。
数组成员总是一个接一个地连续放置,所以对于a
,有两个数组一个接一个地放置:
a: { { -1, -1, -1 }, {-1, -1, -1 } }
对于实际上完全相同p
,每个成员一个接一个地连续跟随;只是,这一次,成员是真正的指针(即内存中的某个地址(。还有其他数组,但这些(必须(放置在其他地方:
p: { <pointer>, <pointer> }
| |
V |
{ 1, 2, 3} |
V
{ 4, 5, 6}
所以总而言之,你的猜测是正确的。
您必须每行执行一个memcpy
才能获得预期的结果:
memcpy(a[0], p[0], 3 * sizeof(int));
memcpy(a[1], p[1], 3 * sizeof(int));
原因是行不连续。
活在神霹雳上
你在混合东西...
另一个问题(尤其是公认的答案(很好地解释了它。 您有一个静态二维数组和一个int**
。
这两个看起来相同,但事实并非如此。编译器知道哪个是哪个,所以一个是连续布局的,另一个不是。
您甚至可以在代码中看到这一点。 一旦你写
int a[2][3]={{-1,-1,-1},
{-1,-1,-1}};
其中对象是用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++;
}
}
其中有一个对象p
.然后用行p[i] = new int[3]
继续制作 2 个单独的int[3]
对象。 这些谎言谁知道在哪里。并且它们的地址被分配给指针p[i]
.
TL;博士:int[2][3]
类型与int**
有根本的不同,它们不是微不足道的互操作。
相关文章:
- C#中等价的C++内存复制
- 坚持将双指针管理的内存复制到二维数组
- OpenCL 将字符从全局内存复制到本地内存
- 内存C++复制是否将内存地址复制到另一个阵列
- 将内存复制到结构时,exc_bad_access
- 动态内存复制是如何工作的
- Cuda-从设备全局内存复制到纹理内存
- 使用动态内存复制类
- 将内存复制到标准::复制
- 通过指针的内存复制有时会丢失数据
- 内存访问与内存复制
- 使用汇编代码从内存复制到c++中的寄存器
- 执行 SSE 内存复制导致的堆损坏 - CRT 检查找不到任何内容
- 内存复制导致偏移量
- 如何将图像从全局内存复制到openCL的本地内存
- 从cuda 3D内存复制到线性内存:复制的数据不是我所期望的
- 使用内存复制对象时出现双自由或损坏错误
- c++内存复制结构体到字节数组中
- 使用内存复制对象数组
- 将原始数据从内存复制到文件(cuda)