c - 制作结构的深拷贝...制作结构的浅拷贝

标签 c struct

有类似这个的问题,但它们与我的具体问题不够相似,我无法接受。

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

假设我们有这个:

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

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

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 副本的尝试。

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;

}

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

阅读有用的评论后编辑:

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

深拷贝:

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

最佳答案

您列为进行浅拷贝的代码不是;它实际上会破坏堆栈并可能使程序崩溃。

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 之后内存中的任何内容。要进行真正的浅拷贝,请不要使用 &:

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

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

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 首先复制名称(或者包括“应该释放”标志,这样您就不必复制文字字符串)。

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

关于c - 制作结构的深拷贝...制作结构的浅拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6911688/

相关文章:

c++ - 有什么理由使用 switch 语句而不是 if 和 elseif 字符串吗?

c - 按值将 C 结构返回给 Julia

json - 在 Go 中,如何将 JSON 对象数组转换为具有默认值的结构数组?

c - 使用将 void 指针重新定义为指向匿名结构的指针?

c++ - 等待时间过去而不用在C窗口中忙着等待

c - 调试意外终止的守护进程

c++ - 为什么这个结构不是标准布局?

c - 在 C 中,全局结构的成员是否默认初始化为零?

c - 使用函数指针、结构、 union 和枚举进行子类型化

c - 如何将链接列表传递给c中的函数