我初始化了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));
Dies,exception:MPITemplate.exe中0x011D5626处的未处理异常:0xC0000005:访问冲突写入位置0x00000000。
函数中的&符号通常表示通过引用传递,当给予memcpy时它如何发挥作用,如果它最终写入相同的块会有什么不同呢?
如果有人可以详细告诉我这些操作发生了什么,我会很感激,因为我可以帮助它完成它的工作,但是我宁愿理解这些调用时实际发生了什么。
谢谢,
麦克
答案 0 :(得分:3)
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
秒。
答案 1 :(得分:3)
你遗漏了声明 添加类型,
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 :(得分:2)
我初始化了2个数组:
不,你不是。您没有显示x
和xPlus1
定义,但如果它们是以下数组:
double x[10];
你的代码不会编译。因此,假设您的代码编译x
和xPlus1
指针加倍。它们很接近,但不是一回事。
首先,我不确定x或xPlus1到底是什么,指向一个充满双打的数组的指针,还是一个充满双打指针的数组? :/
您应该再次发布他们的定义,然后您的问题没有任何意义。它们是指针,你分配给它们的任何东西都不会改变这个事实。所以它们是指向内存块大小sizeof(double) * n
的地址的指针。记忆中的内容取决于您,您可以将其视为双打数组,或其他大小小于或等于sizeof(double) * n
的内容。
但是使用......
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
因此第一行代码复制sizeof(double *)可能是8个字节,即一个double(这只是在64位平台sizeof(double *)== sizeof(double)上的coincedence)来自{{1}指向的内存}由xPlus1
指向的内存。所以你基本上复制了一个元素和相同的(如果你在32位平台上,你只需复制一半的双倍):
x
第二行复制了内存,其中指针x[0] = xPlus1[0];
位于由xPlus1
指向的内存块。因此,您将x
复制到double *
x [0],这没有多大意义:
double
此代码:
x[0] = (double) xPlus1;
基本上这样做(只是令人费解的方式):
memcpy(&x, &xPlus1, sizeof(x));
以下代码:
x = xPlus1;
相当于:
memcpy(&x, xPlus1, sizeof(x));
使得x = (double *)xPlus1[0];
指针具有导致异常的垃圾地址。
所以你的实际代码应该是:
x