在 C 中使用 char 数组深度复制结构(如何复制数组?)
Deep copying structs with char arrays in C (How to copy the arrays?)
我的 C 程序中有以下结构
struct person {
char key[50];
char color[20];
int age;
};
我想深拷贝这个结构。我已经设置了深度复制功能,但是我对如何深度复制字符串有点困惑。我听说有人使用 strcpy
,而其他人使用 strdup
。
我的程序中想要的是当原人被释放时深拷贝的人的key和color不受影响。一旦设置,键和颜色就不能改变。出于我的目的,我应该使用 strcpy
还是 strdup
函数?
strcpy()
和strdup()
有区别。
strdup()
分配 space 和 returns 指向字符串副本的指针,您还必须 free()
返回的指针。
strcpy()
获取分配的 space 并将字符串复制到其中。
在你的情况下它似乎是 strcpy()
因为你的结构的字段不是指针所以你不能给它们分配一个指向已分配 space 的指针,这就是 strdup()
returns.
但是,如 中所述,您实际上不需要。
如果你使用strcpy()
你必须自己分配内存。 strdup()
会为您做到这一点。您可以使用其中任何一个来创建一个与原始内存块分开的新内存块,但自然 strdup()
更简单,因为它不需要单独的 malloc(strlen())
调用。
Post-K&R(即在标准 C 中)您可以直接分配它们。下面的函数只是为了让例子更清楚,你总是会就地分配:
void deepCopyPerson(struct person *target, struct person *src)
{
*target = *src;
}
详细说明:char 数组是结构对象的一部分(真正的数组,不仅仅是指针!),因此与对象一起分配和复制。
为了让不相信的人满意 ;-) 我翻阅了标准草案 1570 :
6.5.16 Assignment operators
Semantics
An assignment operator stores a value in the object designated by the left operand. [Followed by type conversion and sequencing considerations which are not relevant here.]
[...]
6.5.16.1 Simple assignment
Constraints
One of the following shall hold:
[...]
the left operand
has an atomic, qualified, or unqualified version of a structure or
union type compatible with the type of the right;
[...]
Semantics
In simple assignment (=), the value of the right operand is converted
to the type of the assignment expression and replaces the value stored
in the object designated by the left operand.
要执行包含数组(没有任何指针)的结构的深拷贝,深拷贝很简单
struct person x = {"Key", "Color", 42}; /* initialise to something */
struct person y = x;
如果 "strings" 是指针,这将不起作用。然后有必要分配新的字符串,然后使用类似 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;
}
上面遗漏了一些错误检查(例如,需要在复制前检查 malloc()
是否成功)。
我的 C 程序中有以下结构
struct person {
char key[50];
char color[20];
int age;
};
我想深拷贝这个结构。我已经设置了深度复制功能,但是我对如何深度复制字符串有点困惑。我听说有人使用 strcpy
,而其他人使用 strdup
。
我的程序中想要的是当原人被释放时深拷贝的人的key和color不受影响。一旦设置,键和颜色就不能改变。出于我的目的,我应该使用 strcpy
还是 strdup
函数?
strcpy()
和strdup()
有区别。
strdup()
分配 space 和 returns 指向字符串副本的指针,您还必须free()
返回的指针。strcpy()
获取分配的 space 并将字符串复制到其中。
在你的情况下它似乎是 strcpy()
因为你的结构的字段不是指针所以你不能给它们分配一个指向已分配 space 的指针,这就是 strdup()
returns.
但是,如
如果你使用strcpy()
你必须自己分配内存。 strdup()
会为您做到这一点。您可以使用其中任何一个来创建一个与原始内存块分开的新内存块,但自然 strdup()
更简单,因为它不需要单独的 malloc(strlen())
调用。
Post-K&R(即在标准 C 中)您可以直接分配它们。下面的函数只是为了让例子更清楚,你总是会就地分配:
void deepCopyPerson(struct person *target, struct person *src)
{
*target = *src;
}
详细说明:char 数组是结构对象的一部分(真正的数组,不仅仅是指针!),因此与对象一起分配和复制。
为了让不相信的人满意 ;-) 我翻阅了标准草案 1570 :
6.5.16 Assignment operators
Semantics
An assignment operator stores a value in the object designated by the left operand. [Followed by type conversion and sequencing considerations which are not relevant here.]
[...]
6.5.16.1 Simple assignment
Constraints
One of the following shall hold:
[...]
the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
[...]
Semantics
In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.
要执行包含数组(没有任何指针)的结构的深拷贝,深拷贝很简单
struct person x = {"Key", "Color", 42}; /* initialise to something */
struct person y = x;
如果 "strings" 是指针,这将不起作用。然后有必要分配新的字符串,然后使用类似 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;
}
上面遗漏了一些错误检查(例如,需要在复制前检查 malloc()
是否成功)。