繁体   English   中英

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

[英]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时如何显示引用,如果最后要写相同的块,这会有什么区别?

如果有人可以详细告诉我这些操作的进展,我将不胜感激,因为我可以摆弄它的工作原理,但我宁愿了解进行这些调用时的实际情况。

谢谢,

麦克风

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 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个数组:

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

double x[10];

您的代码无法编译。 因此,假设您的代码编译xxPlus1是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM