通过 memcpy 函数保存临时值

Save temporary values by memcpy function

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    float *stack=NULL, *tmp1=NULL;
    int i;
    
    stack = (float *) malloc(sizeof(float)*4);
    tmp1 = (float *) malloc(sizeof(float)*4);
    
    stack[0]=1.0; stack[1]=1.1; stack[2]=1.2; stack[3]=1.3;
    
    memcpy(tmp1,stack,4*sizeof(float));
    
    for(i=0;i<4;i++){
        
        printf("stack[%d]=%f, tmp1[%d]=%f\n",i,stack[i],i,tmp1[i]);
    }
    
    stack[0]=2.0; stack[1]=2.1; stack[2]=2.2; stack[3]=2.3;
    
    for(i=0;i<4;i++){
        
        printf("stack[%d]=%f, tmp1[%d]=%f\n",i,stack[i],i,tmp1[i]);
    }

    return 0;
}

结果是:

stack[0]=1.000000, tmp1[0]=1.000000                                                                                                                                                
stack[1]=1.100000, tmp1[1]=1.100000                                                                                                                                                
stack[2]=1.200000, tmp1[2]=1.200000                                                                                                                                                
stack[3]=1.300000, tmp1[3]=1.300000                                                                                                                                                
stack[0]=2.000000, tmp1[0]=1.000000                                                                                                                                                
stack[1]=2.100000, tmp1[1]=1.100000                                                                                                                                                
stack[2]=2.200000, tmp1[2]=1.200000                                                                                                                                                
stack[3]=2.300000, tmp1[3]=1.300000

我的问题是:memcpy 获取stack 的整个内存位置,并将其复制到tmp1。我的期望是我只需要更改 stack,因此 tmp1 会相应更改。但在此示例中,tmp1 不会更改为 stack

如果我想在更改 stack 时更改 tmp1,我需要添加一行。见下文:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    float *stack=NULL, *tmp1=NULL;
    int i;
    
    stack = (float *) malloc(4);
    tmp1 = (float *) malloc(4);
    
    stack[0]=1.0; stack[1]=1.1; stack[2]=1.2; stack[3]=1.3;
    
    memcpy(tmp1,stack,4*sizeof(float));
    
    for(i=0;i<4;i++){
        
        printf("stack[%d]=%f, tmp1[%d]=%f\n",i,stack[i],i,tmp1[i]);
    }
    
    stack[0]=2.0; stack[1]=2.1; stack[2]=2.2; stack[3]=2.3;
    
    memcpy(tmp1,stack,4*sizeof(float)); /* I add this line here */

    for(i=0;i<4;i++){
        
        printf("stack[%d]=%f, tmp1[%d]=%f\n",i,stack[i],i,tmp1[i]);
    }

    return 0;
}

那么,结果是:

stack[0]=1.000000, tmp1[0]=1.000000                                                                                                                                                
stack[1]=1.100000, tmp1[1]=1.100000                                                                                                                                                
stack[2]=1.200000, tmp1[2]=1.200000                                                                                                                                                
stack[3]=1.300000, tmp1[3]=1.300000                                                                                                                                                
stack[0]=2.000000, tmp1[0]=2.000000                                                                                                                                                
stack[1]=2.100000, tmp1[1]=2.100000                                                                                                                                                
stack[2]=2.200000, tmp1[2]=2.200000                                                                                                                                                
stack[3]=2.300000, tmp1[3]=2.300000 

有人解释为什么吗?

至少这个问题:内存分配不足

stack = (float *) malloc(4);  // Not enough
stack[0]=1.0; stack[1]=1.1; stack[2]=1.2; stack[3]=1.3;

避免使用无类型

编码不正确的类型
stack = malloc(sizeof *stack * 4);
if (stack) { // Success
  stack[0]=1.0; stack[1]=1.1; stack[2]=1.2; stack[3]=1.3;
  ...

tmp1 相同。


My expectation is that I only need to change stack, and therefore tmp1 will change accordingly.

OP 的代码无法满足这种期望,因为 stacktmp1 之间没有联系或链接,只是它们碰巧具有相同的数据。

改变一个不会改变另一个。

My question is: memcpy takes the whole memory location of stack, and copy it to tmp1. My expectation is that I only need to change stack, and therefore tmp1 will change accordingly. But in this example, tmp1 does not change as stack.

有问题的行是这样的:

    memcpy(tmp1,stack,4*sizeof(float));

stack指向的内存的内容复制到tmp1指向的space中。您现在有两个独立的数据副本。它不会使 tmp1stack 成为彼此的别名。当然,如果您修改一个副本,则更改不会反映在另一个副本中。

If I want to change tmp1 as I change stack, I need to add one additional line [...]:

    memcpy(tmp1,stack,4*sizeof(float)); /* I add this line here */

是的,您可以通过将一个内存块的内容复制到另一个内存块来随时同步两个内存块的内容。那仍然不会产生任何别名。整个事情类似于:

int a;
int b;

a = 1;
b = a;

printf("a=%d, b=%d\n", a, b);
// prints a=1, b=1

a = 2;

printf("a=%d, b=%d\n", a, b);
// prints a=2, b=1

b = a;

printf("a=%d, b=%d\n", a, b);
// prints a=2, b=2

赋值,例如a = b复制b的值a,就像memcpy()复制指向的值一样通过一个指针指向另一个指针指向的 space 。随后修改 a 不会导致 b 的值发生变化,就像修改 stack 指向的值不会导致 tmp1 指向的值发生变化一样,当然,您可以随时重新同步。

如果你想使 tmp1 成为 stack 的别名,那么你想复制 指针 ,而不是它指向的数据:

float *stack, *tmp1;

stack = malloc(4 * sizeof(*stack));
tmp1 = stack;  // Now stack and tmp1 point to the same memory

stack[0] = 1.0;
stack[1] = 1.1;
stack[2] = 1.2;
stack[3] = 1.3;

// no memcpy here

for (int i = 0; i < 4; i++) {
    printf("stack[%d]=%f, tmp1[%d]=%f\n", i, stack[i], i, tmp1[i]);
}