简体   繁体   English

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

[英]How does memcpy work on pointers to arrays?

I initialise 2 arrays like so: 我像这样初始化2个数组:

x = (double*) malloc(sizeof(double)*n);
xPlus1 = (double*) malloc(sizeof(double)*n);

Firstly, I'm not certain of exactly what x or xPlus1 now are, a pointer to an array full of doubles, or an array full of pointers to doubles? 首先,我不确定确切是什么x或xPlus1,是指向充满双打的数组的指针,还是充满指向双打的指针的数组? :/ :/

The answer to that question probably effects this but if I do these various operations, I can't get it to do what I want, which is just to copy the values from xPlus1 into x. 该问题的答案可能会影响这一点,但是如果执行这些各种操作,我将无法完成我想要的操作,这仅仅是将xPlus1中的值复制到x中。 xPlus1 and x do hold different values for each index, because printing after a simple for loop achieves the desired effect: xPlus1和x的每个索引确实具有不同的值,因为在简单的for循环之后进行打印可获得所需的效果:

for (int i = 0; i < n; i++) {
    x[i] = xPlus1[i];
}

But using... 但是使用...

memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x)); 

If I access x after either of these in the same function, x is unchanged, kept it's old values. 如果我在同一函数中的任何一个之后访问x,则x保持不变,保留其旧值。

memcpy(&x, &xPlus1, sizeof(x)); 

I believe this makes x and xPlus1 point to the same memory location by the outputs I get. 我相信这会使x和xPlus1通过我得到的输出指向相同的内存位置。 This is because if I modify x or xPlus1 after this copy, then both values change if I print both arrays. 这是因为如果在此副本之后修改x或xPlus1,则如果我同时打印两个数组,则两个值都会更改。

memcpy(&x, xPlus1, sizeof(x)); 

Dies, exception: Unhandled exception at 0x011D5626 in MPITemplate.exe: 0xC0000005: Access violation writing location 0x00000000. 死,异常:MPITemplate.exe中0x011D5626处未处理的异常:0xC0000005:访问冲突写入位置0x00000000。

The ampersand in functions usually indicate a pass by reference, how does this play out when given to memcpy, and what difference does it make if it's going to write to the same blocks in the end? 函数中的&符通常表示按引用传递,给与memcpy时如何显示引用,如果最后要写相同的块,这会有什么区别?

I'd appreciate if someone could tell me in detail what's going on with these operations, because I can fiddle around making it work but I'd rather understand what's actually happening when these calls are made. 如果有人可以详细告诉我这些操作的进展,我将不胜感激,因为我可以摆弄它的工作原理,但我宁愿了解进行这些调用时的实际情况。

Thanks, 谢谢,

Mike 麦克风

Both x and xPlus1 should be of type double* . xxPlus1都应为double*类型。 They are pointers to an array of n doubles. 它们是n双精度数组的指针。

So when you do this: 因此,当您执行此操作时:

memcpy(x, xPlus1, sizeof(x));

Since x is just a double* , that only copies sizeof(double*) bytes... which is to say, 8. What you want to do is: 由于x只是double* ,因此仅复制sizeof(double*)个字节...也就是说8。您要做的是:

memcpy(x, xPlus1, n * sizeof(*x));

because the type of *x is double , so n * sizeof(*x) will be the total bytes of memory that xPlus1 owns: n double s. 因为*x的类型是double ,所以n * sizeof(*x)将是xPlus1拥有的总内存字节: n double s。

You left out the declarations. 您忽略了声明。
Adding the type, 添加类型,

double* x = (double*) malloc(sizeof(double)*n);

makes it clearer that x is a pointer to a double . 更清楚地表明x是指向double的指针。
In this particular case, the double x points to is the first element in an array of n doubles. 在这种情况下,双精度点x指向n双精度点数组中的第一个元素。

Something like this: 像这样:

       (------- n doubles  -----)        
      ___________________________
x ===>| | | | | | | | | | | | | |
      ---------------------------

&x would give you the address of the variable x itself . &x将为您提供变量x本身的地址 This is very different from the address that the variable x contains . 与变量x包含的地址非常不同。
(If you have int x = 1; , &x will most likely not be 1.) (如果int x = 1;&x很可能不是1。)

memcpy takes two pointers, one for the destination and one for the source, and the size of the memory to copy. memcpy需要两个指针,一个指向目标,一个指向源,以及要复制的内存大小。
But sizeof(x) doesn't give you the size of the array you allocated; 但是sizeof(x)不能给您分配的数组的大小。 it gives you the size of x , which is a pointer. 它的大小为x ,它是一个指针。
(Size is measured in multiples of sizeof(char) , which by definition is 1, and sizeof(double*) will be 4 (32 bits) or 8 (64 bits) on most modern machines. So you're copying 32 or 64 bits.) (大小以sizeof(char)倍数度量,其定义为1,在大多数现代机器上, sizeof(double*)将为4(32位)或8(64位)。因此,您要复制32或64位。)

The size parameter should be the same size that you passed to malloc , if you want to copy the whole thing. 如果要复制整个内容,则size参数应该与传递给malloc大小相同。
The pointers should be the ones returned from malloc , since these are the memory blocks you want to copy. 指针应该是从malloc返回的指针,因为这些是您要复制的内存块。

So, 所以,

memcpy(x, xPlus1, sizeof(double) * n);

should work as expected. 应该能按预期工作。

I initialise 2 arrays like so: 我像这样初始化2个数组:

No you are not. 不,你不是。 You did not show x and xPlus1 definition, but if they are arrays like: 您没有显示xxPlus1定义,但是如果它们是如下数组:

double x[10];

your code wouldn't compile. 您的代码无法编译。 So assuming your code compiles x and xPlus1 are pointers to double. 因此,假设您的代码编译xxPlus1是double的指针 They are close, but not the same thing. 它们很接近,但不一样。

Firstly, I'm not certain of exactly what x or xPlus1 now are, a pointer to an array full of doubles, or an array full of pointers to doubles? 首先,我不确定确切是什么x或xPlus1,是指向充满双打的数组的指针,还是充满指向双打的指针的数组? :/ :/

Again you should publish their definition and then your question would not make any sense. 同样,您应该发布它们的定义,然后您的问题将变得毫无意义。 They are pointers and whatever you assign to them does not change that fact. 它们是指针,您分配给它们的任何内容都不会改变这一事实。 So they are pointers holding address of memory block size sizeof(double) * n . 因此,它们是保存内存块大小为sizeof(double) * n地址的指针。 What will be in that memory depends on you, you can treat it as array of doubles, or something else that has size less or equal to sizeof(double) * n . 内存中的内容取决于您,您可以将其视为double数组,或者其他大小小于或等于sizeof(double) * n

But using... 但是使用...

memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x)); 

So first line of code copies sizeof( double * ) probably 8 bytes ie one double (which is just coincedence that on 64 bit platform sizeof( double * ) == sizeof( double ) ) from memory pointed by xPlus1 to memory pointed by x . 因此,第一行代码从xPlus1指向的内存到x指向的内存复制sizeof(double *)可能是8个字节,即一个double(在64位平台上sizeof(double *)== sizeof(double)是一致的)。 So you basically copied one element and that the same as (if you are on 32 bit platform you would just copy half of double): 因此,您基本上复制了一个元素,并且与之相同(如果您在32位平台上,则只需复制double的一半):

x[0] = xPlus1[0]; 

Second line copied memory where pointer xPlus1 located to memory block pointed by x . 第二行复制了内存,其中指针xPlus1指向x指向的内存块。 So you copied double * to double x[0] which does not make much sense: 因此,您将double *复制到double x [0]并没有多大意义:

x[0] = (double) xPlus1;

This code: 这段代码:

memcpy(&x, &xPlus1, sizeof(x)); 

basically did this (just convoluted way): 基本上做到了这一点(只是令人费解的方式):

x = xPlus1;

Following code: 以下代码:

memcpy(&x, xPlus1, sizeof(x)); 

is equivalent to this: 等效于此:

x = (double *)xPlus1[0]; 

which makes x pointer to have garbage address which leads to exception. 这使得x指针具有导致异常的垃圾地址。

So your actual code should be: 因此,您的实际代码应为:

memcpy( x, xPlus1, sizeof( double ) * n );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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