在C中使用char数组深度复制结构

Ard*_*bly 5 c struct deep-copy

我的C程序中有以下结构

struct person {
    char key[50];
    char color[20];
    int age;
};
Run Code Online (Sandbox Code Playgroud)

我想制作一个这个结构的深层副本.我有深度复制功能设置但是我对如何深度复制字符串有点困惑.我听说有人使用strcpy和其他人使用strdup.

在我的程序中我想要的是,如果原始人被释放,深度复制的人的密钥和颜色不会受到影响.设置后,键和颜色不能改变.为了我的目的,我应该使用strcpystrdup功能吗?

Pet*_*ica 7

在K&R之后(即在标准C中),您只需分配它们即可。下面的功能只是为了使示例更清楚,您始终只能就地分配:

void deepCopyPerson(struct person *target, struct person *src)
{
    *target = *src;
}
Run Code Online (Sandbox Code Playgroud)

详细说明:char数组是struct对象的一部分(真正的数组,不仅是指针!),因此与对象一起分配和复制。

为了满足不信任的人;-)我在标准草案1570中进行了挖掘:

6.5.16赋值运算符

语义学

赋值运算符将一个值存储在由左操作数指定的对象中。[之后是与类型转换和排序有关的注意事项,此处不相关。]

[...]

6.5.16.1简单分配

约束条件

以下条件之一应成立:

  • [...]

  • 左操作数具有与右类型兼容的结构或联合类型的原子,合格或不合格版本;

[...]

语义学

简单赋值(=)中,将右操作数的值转换为赋值表达式的类型,并替换存储在由左操作数指定的对象中的值。


Pet*_*ter 5

要执行包含数组(没有任何指针)的结构的深层副本,深层副本很简单

struct person x = {"Key", "Color", 42};   /*  initialise to something */
struct person y = x;
Run Code Online (Sandbox Code Playgroud)

如果"字符串"是指针,这不起作用.然后有必要分配新的字符串,然后使用strcpy()之类的函数来复制成员.

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

struct pointer_person
{
    char *key;
    char *color;
    int age;
};

struct pointer_person deep_copy(struct pointer_person p)
{
     struct pointer_person retval;
     retval.key = malloc(strlen(p.key) + 1);
     strcpy(retval.key, p.key);
     retval.color = malloc(strlen(p.color) + 1);
     strcpy(retval.color, p.color);
     retval.age = p->age;
     return retval;
}

int main()
{
   struct pointer_person p;
   struct pointer_person pc;

   p.key = malloc(50);
   strcpy(p.key, "A key");
   p.color = malloc(20);
   strcpy(p.color, "A colour");
   p.key = 42;

   pc = deep_copy(p);

   /* do stuff with pc and c */

   free(p.key);
   free(p.color);
   free(pc.key);
   free(pc.color);
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

从上面遗漏了一些错误检查(例如,需要malloc()在复制前检查是否成功).


Iha*_*imi -1

strcpy()和之间是有区别的strdup()

  • strdup()分配空间并返回指向字符串副本的指针,您还必须free()返回返回的指针。

  • strcpy()获取分配的空间并将字符串复制到其中。

在您的情况下,似乎是strcpy()因为结构体的字段不是指针,所以您不能为它们分配一个指向分配空间的指针,这就是strdup()返回的空间。

但是,正如此答案中所解释的,您实际上不需要这样做。

  • 内存复制给定的结构没有多大意义。该语言有一个现成的内置赋值工具,恰当地命名为赋值运算符“=”。 (5认同)