[英]How does memcpy work on pointers to arrays?
我像这样初始化2个数组:
x = (double*) malloc(sizeof(double)*n);
xPlus1 = (double*) malloc(sizeof(double)*n);
首先,我不确定确切是什么x或xPlus1,是指向充满双打的数组的指针,还是充满指向双打的指针的数组? :/
该问题的答案可能会影响这一点,但是如果执行这些各种操作,我将无法完成我想要的操作,这仅仅是将xPlus1中的值复制到x中。 xPlus1和x的每个索引确实具有不同的值,因为在简单的for循环之后进行打印可获得所需的效果:
for (int i = 0; i < n; i++) {
x[i] = xPlus1[i];
}
但是使用...
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
如果我在同一函数中的任何一个之后访问x,则x保持不变,保留其旧值。
memcpy(&x, &xPlus1, sizeof(x));
我相信这会使x和xPlus1通过我得到的输出指向相同的内存位置。 这是因为如果在此副本之后修改x或xPlus1,则如果我同时打印两个数组,则两个值都会更改。
memcpy(&x, xPlus1, sizeof(x));
死,异常:MPITemplate.exe中0x011D5626处未处理的异常:0xC0000005:访问冲突写入位置0x00000000。
函数中的&符通常表示按引用传递,给与memcpy时如何显示引用,如果最后要写相同的块,这会有什么区别?
如果有人可以详细告诉我这些操作的进展,我将不胜感激,因为我可以摆弄它的工作原理,但我宁愿了解进行这些调用时的实际情况。
谢谢,
麦克风
x
和xPlus1
都应为double*
类型。 它们是n
双精度数组的指针。
因此,当您执行此操作时:
memcpy(x, xPlus1, sizeof(x));
由于x
只是double*
,因此仅复制sizeof(double*)
个字节...也就是说8。您要做的是:
memcpy(x, xPlus1, n * sizeof(*x));
因为*x
的类型是double
,所以n * sizeof(*x)
将是xPlus1
拥有的总内存字节: n
double
s。
您忽略了声明。
添加类型,
double* x = (double*) malloc(sizeof(double)*n);
更清楚地表明x
是指向double
的指针。
在这种情况下,双精度点x
指向n
双精度点数组中的第一个元素。
像这样:
(------- n doubles -----)
___________________________
x ===>| | | | | | | | | | | | | |
---------------------------
&x
将为您提供变量x
本身的地址 。 这与变量x
包含的地址非常不同。
(如果int x = 1;
, &x
很可能不是1。)
memcpy
需要两个指针,一个指向目标,一个指向源,以及要复制的内存大小。
但是sizeof(x)
不能给您分配的数组的大小。 它的大小为x
,它是一个指针。
(大小以sizeof(char)
倍数度量,其定义为1,在大多数现代机器上, sizeof(double*)
将为4(32位)或8(64位)。因此,您要复制32或64位。)
如果要复制整个内容,则size参数应该与传递给malloc
大小相同。
指针应该是从malloc
返回的指针,因为这些是您要复制的内存块。
所以,
memcpy(x, xPlus1, sizeof(double) * n);
应该能按预期工作。
我像这样初始化2个数组:
不,你不是。 您没有显示x
和xPlus1
定义,但是如果它们是如下数组:
double x[10];
您的代码无法编译。 因此,假设您的代码编译x
和xPlus1
是double的指针 。 它们很接近,但不一样。
首先,我不确定确切是什么x或xPlus1,是指向充满双打的数组的指针,还是充满指向双打的指针的数组? :/
同样,您应该发布它们的定义,然后您的问题将变得毫无意义。 它们是指针,您分配给它们的任何内容都不会改变这一事实。 因此,它们是保存内存块大小为sizeof(double) * n
地址的指针。 内存中的内容取决于您,您可以将其视为double数组,或者其他大小小于或等于sizeof(double) * n
。
但是使用...
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
因此,第一行代码从xPlus1
指向的内存到x
指向的内存复制sizeof(double *)可能是8个字节,即一个double(在64位平台上sizeof(double *)== sizeof(double)是一致的)。 因此,您基本上复制了一个元素,并且与之相同(如果您在32位平台上,则只需复制double的一半):
x[0] = xPlus1[0];
第二行复制了内存,其中指针xPlus1
指向x
指向的内存块。 因此,您将double *
复制到double
x [0]并没有多大意义:
x[0] = (double) xPlus1;
这段代码:
memcpy(&x, &xPlus1, sizeof(x));
基本上做到了这一点(只是令人费解的方式):
x = xPlus1;
以下代码:
memcpy(&x, xPlus1, sizeof(x));
等效于此:
x = (double *)xPlus1[0];
这使得x
指针具有导致异常的垃圾地址。
因此,您的实际代码应为:
memcpy( x, xPlus1, sizeof( double ) * n );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.