C:制作一个结构的深层副本......让一个结构的浅表副本 [英] C: Making a deep copy of a struct...making a shallow copy of a struct

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

问题描述

在我得到高度downvoted,我会提到,有像这样的我已经看到了问题,但他们都没有我的具体问题很相似,让我挑上,至少(请原谅我的无知在情况下)或它们不一定Q-特定

Before I get highly downvoted, I will mention that there are questions LIKE this one I have already seen, but they all are not similar enough to my specific question FOR ME to pick up on, at least (excuse my ignorance in that case) or they are not necessarily C-specific.

我的问题是如何使一个结构的深层副本的指针作为成员,以及如何使一个结构的浅表副本成员是指针。然后,仅供参考,如何让一个结构的深拷贝无指针成员以及如何使一个结构的浅表副本,而不指针成员(不知道这最后一个有意义)。

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 members that are pointers. 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).

让我们说我们有这样的:

Let's say we have this:

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 please bear with me):

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;
}

现在我会尝试深和浅拷贝;告诉我,如果我做了什么愚蠢的。

Now I will attempt to make a deep and a shallow copy; tell me if I do something stupid

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;
}

现在,对于具有指针成员结构的深层副本我知道我们必须使我们自己的复制功能,做一些明智的指针。那明智的事情是什么......我不知道......所以这里就是在这个深拷贝我的(可能是可怜的)尝试。

Now, 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 (probably pathetic) attempt at this DEEP copy.

void copy_Student(Student *s1, Student *s2)
{
   s2 -> grade = s1 -> grade;
   s2 -> id = s2 -> 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.

好吧,编辑看完了有益的意见:

Okay, EDITED AFTER READING HELPFUL COMMENTS:

浅拷贝:
        的memcpy(S2,S1,sizeof的(学生));

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 = s2 -> id;
    s2 -> first_name = strdup(s1 -> first_name);
    s2 -> last_name = strdup(s1 -> last_name);
}

谢谢你们(一定要指出,如果仍然有错误,虽然)!

Thanks guys (be sure to point out if there still are errors, though)!

太感谢了,
菲尔

Thanks so much, Phil

推荐答案

您已经列为使得浅拷贝的code不是;它实际上将破坏堆栈,可能引起程序崩溃。

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

在code你有一个深刻的副本同样是错的,但你在正确的轨道上。背后深层副本的基本想法是,你必须给每个字段复制;对于非指针类型,这是一样的浅拷贝,但对于指针,你必须做一些更聪明。在code你贴出来,但是,不这样做。试试这个吧。

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.

这篇关于C:制作一个结构的深层副本......让一个结构的浅表副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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