制作结构的深拷贝...制作结构的浅拷贝 [英] Making a deep copy of a struct...making a shallow copy of a struct

查看:31
本文介绍了制作结构的深拷贝...制作结构的浅拷贝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有类似这个问题的问题,但它们与我的具体问题不够相似,我无法回答.

There are questions LIKE this one, but they are not similar enough to my specific question FOR ME to pick up on.

我的问题是关于如何制作以指针为成员的结构的深拷贝,以及如何制作以指针为成员的结构的浅拷贝.然后,仅供参考,如何制作没有指针成员的结构的深拷贝以及如何制作没有指针成员的结构的浅拷贝(不确定最后一个是否有意义).

My question is about how to make a deep copy of a struct with pointers as members and how to make a SHALLOW copy of a struct with pointers as members. And then, just for reference, how to make a a deep copy of a struct WITHOUT pointer members and how to make a shallow copy of a struct WITHOUT pointer members (not sure if that last one makes sense).

假设我们有这个:

typedef struct Student
{
    char* first_name; 
    char* last_name; 
    int grade;
    long id;
} Student;

这是我用来创建学生的通用函数(标题难以格式化):

Here is a generic function I made to create a student (the header is being difficult to format):

Student* create_student(const char* first_name, const char* last_name, int grade,long id)

{

   Student *newStudentp = (malloc(sizeof(Student)));

   newStudentp -> last_name = (malloc((strlen(last_name) + 1)  * sizeof(char)));
   newStudentp -> first_name = (malloc((strlen(first_name) + 1)  * sizeof(char)));

   strncpy(newStudentp -> first_name, first_name, strlen(first_name) + 1);
   strncpy(newStudentp -> last_name, last_name, strlen(last_name) + 1);

   newStudentp -> grade = grade;
   newStudentp -> id = id;


   return newStudentp;
}

我尝试制作深浅副本;

int main()
{
    Student *s1 = create_Student("Bo","Diddly", 100, 221);
    Student *s2 = create_Student("Leeroy","Jenkins",50,1337);
    memcpy(&s2,&s1,sizeof(Student)); //shallow copy of s1 INTO s2?
    return 0;
}

对于带有指针成员的结构体的深层副本,我知道我们必须制作我们自己的复制函数,它可以对指针做一些有意义的事情.什么是明智的事情...我不确定...所以这是我对这个 DEEP 副本的尝试.

For deep copies of structs with pointer members I know we must make OUR OWN copy function that does something sensible with pointers. What that sensible thing is...I'm not sure...so here is my attempt at this DEEP copy.

void copy_Student(Student *s1, Student *s2)
{
   s2 -> grade = s1 -> grade;
   s2 -> id = s1 -> id;
   s2 -> first_name = s1 -> *first_name;
   s2 -> last_name = s1 -> *last_name;

}

我的问题的另一部分(没有指针作为成员的结构)可能只能口头解释.

The other part of my question (structs WITHOUT pointers as members) can probably just be explained verbally.

阅读有用评论后

浅拷贝:memcpy(s2,s1,sizeof(Student));

Shallow copy: memcpy(s2,s1,sizeof(Student));

深拷贝:

void free_student(Student* stu)
{
    free(stu -> first_name);
    free(stu -> last_name);
}

void copy_Student(Student *s1, Student *s2)
{
    s2 -> grade = s1 -> grade;
    s2 -> id = s1 -> id;
    s2 -> first_name = strdup(s1 -> first_name);
    s2 -> last_name = strdup(s1 -> last_name);
}

推荐答案

您列出的用于制作浅拷贝的代码不是;它实际上会粉碎堆栈并可能使程序崩溃.

The code you have listed as making a shallow copy isn't; it will actually smash the stack and probably crash the program.

Student *s1 = create_Student("Bo","Diddly", 100, 221);
Student *s2 = create_Student("Leeroy","Jenkins",50,1337);
memcpy(&s2,&s1,sizeof(Student)); //shallow copy of s1 INTO s2?

如果您的尺寸合适,则与 s2 = s1; 相同.但是由于您的大小错误,它复制了太多并且会在 s2 之后覆盖内存中的任何内容.要进行真正的浅拷贝,请不要使用 &:

If you had the size right, that would be the same as s2 = s1;. But since you have the size wrong, it is copying too much and will overwrite whatever is in memory after s2. To do a real shallow copy, leave off the &:

memcpy(s2,s1,sizeof(Student)); //shallow copy of s1 INTO s2

您拥有的用于深拷贝的代码同样是错误的,但您走在正确的轨道上.深层复制背后的基本思想是您必须复制每个字段;对于非指针类型,这与浅拷贝相同,但对于指针,您必须做一些更聪明的事情.但是,您发布的代码并没有这样做.试试这个.

The code you have for a deep copy is similarly wrong, but you're on the right track. The basic idea behind a deep copy is that you have to copy each field; for non-pointer types this is the same as a shallow copy, but for pointers you have to do something smarter. The code you posted, however, isn't doing that. Try this instead.

void copy_Student(Student *s1, Student *s2)
{
    s2 -> grade = s1 -> grade;
    s2 -> id = s2 -> id;
    s2 -> first_name = strdup(s1 -> first_name);
    s2 -> last_name = strdup(s1 -> last_name);
}

请注意,为了避免内存泄漏,您还需要在分配新副本之前从 s2 中释放旧名称,创建一个 free_Student 函数来释放这些名称,并确保 create_Student 首先复制名称(或者包括应该释放"标志,这样您就不必复制文字字符串).

Note that to avoid memory leaks, you would also need to free the old names from s2 before assigning the new copies, make a free_Student function that would free these names, and also make sure that create_Student copies the names in the first place (or else include "should free" flags so you don't have to copy literal strings).

现在,对于没有指针(或其他引用类型)的结构,深拷贝和浅拷贝之间没有区别,因为数据结构本身是浅的.

Now, for a struct without pointers (or other reference types), there is no difference between a deep and a shallow copy because the data structure it itself shallow.

这篇关于制作结构的深拷贝...制作结构的浅拷贝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆