memcpy如何处理指向数组的指针?

时间:2014-11-04 15:06:38

标签: c++ c arrays pointers memcpy

我初始化了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时它如何发挥作用,如果它最终写入相同的块会有什么不同呢?

如果有人可以详细告诉我这些操作发生了什么,我会很感激,因为我可以帮助它完成它的工作,但是我宁愿理解这些调用时实际发生了什么。

谢谢,

麦克

3 个答案:

答案 0 :(得分:3)

xxPlus1都应为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个数组:

不,你不是。您没有显示xxPlus1定义,但如果它们是以下数组:

double x[10];

你的代码不会编译。因此,假设您的代码编译xxPlus1 指针加倍。它们很接近,但不是一回事。

  

首先,我不确定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