通过设置解除引用的指针将对象从堆栈复制到堆是一种好习惯吗?

Is it good practice to copy objects from the stack to the heap by setting a dereferenced pointer?

请考虑这个示例程序:

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

typedef struct {
  int a;
  int b;
} X;

int main(void) {
  X* p = malloc(sizeof(X)); // Heap allocation
  X z = {.a = 2, .b = 3}; // Stack allocation
  *p = z; // Copying from the stack onto the heap

  printf("\n%d\n", p->b);

  return 0;
}

此程序正确打印 3。我假设这意味着 *p = z 成功地将 z 的数据从堆栈复制到堆上。

如果可以如此轻松地将内容从堆栈复制到堆,为什么大多数人在尝试这样做时使用 memcpy.

在什么情况下 memcpy 合适,而在什么情况下上述解决方案可以?

当您将一个数组的内容复制到另一个数组时(这些内容不构成 字符串 ),或者当您我们正在尝试将一种类型的对象的内容映射到另一种类型的对象的字节。

例如,如果您将 struct 类型映射到 unsigned char 的数组,您将执行如下操作:

X foo = {1, 2};
unsigned char *bytes = malloc( sizeof foo );
unsigned char sbytes[sizeof foo];

memcpy( bytes, &foo, sizeof foo );
memcpy( sbytes, &foo, sizeof foo );

类似地,如果您试图将一个数组的内容复制到另一个数组并且这些内容不构成 字符串 ,您也可以使用 memcpy:

int src[N];
int *dst = malloc( sizeof src );
int sdst[N];
...
memcpy( dst, src, sizeof src );
memcpy( sdst, src, sizeof src );

如果它们确实构成一个字符串,您将使用 strcpy:

char blah[10];
strcpy( blah, "foo" );

否则,请像您在此处所做的那样使用赋值运算符。

"Is it good practice to copy objects from the stack to the heap by setting a dereferenced pointer?"

是的。 *p = z; 很好。优于 memcpy():类型检查。

In what situations is memcpy appropriate, versus in what situations is the above solution okay?

  • memcpy:复制数组时

  • memcpy:当source/destination不对齐时(代码需要pack/unpack数据)。

  • 否则:使用简单赋值。