iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言结构体成员赋值的深拷贝与浅拷贝详解
  • 518
分享到

C语言结构体成员赋值的深拷贝与浅拷贝详解

2024-04-02 19:04:59 518人浏览 安东尼
摘要

目录浅拷贝结构体中不存在指针成员变量时结构体中存在指针成员变量时深拷贝结论浅拷贝 C语言中的浅拷贝是指在拷贝过程中,对于指针型成员变量只拷贝指针本身,而不拷贝指针所指向的目标,它按字

浅拷贝

C语言中的浅拷贝是指在拷贝过程中,对于指针型成员变量只拷贝指针本身,而不拷贝指针所指向的目标,它按字节复制的。我们分几种情况举例子来看一下。

结构体中不存在指针成员变量时

代码如下:

#include <stdio.h>
typedef struct {
    char name[64];
    int age;
}Member;
 
int main(){
    Member stu1 = { "LiMing", 18 };
    Member stu2;
    stu2 = stu1;
    printf("%s,%d\n", stu2.name, stu2.age);
    system("pause");
    return 0;
}

运行如下:

结构体中存在指针成员变量时

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1, Member2;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
 
 Member2 = Member1;
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 printf("%s, %d\n", Member1.name, Member1.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 
 system("pause");
 return 0;
}

运行如下:

从中我们看到,改变Member2的值,Member1的值也改变了,这说明一片空间被两个不同的子对象共享了,改变一个对象的值另外一个也会随之改变。

我们改变Member2写法,申请内存的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
  
  Member Member2;
 Member2.name = malloc(sizeof(char) * 64);
 if (NULL == Member2.name)
 {
  printf("malloc failed\n");
 }
 memset(Member2.name, 0, 64);
 //strcpy(Member2.name, "LiMing");
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 Member1 = Member2;
 
 printf("%s, %d\n", Member2.name, Member2.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 if (NULL != Member2.name) {
  free(Member2.name);
  Member2.name = NULL;
 }
 system("pause");
 return 0;
}

运行如下:

从中我们看到,当数据成员中有指针时,两个类中的两个指针将指向同一个地址,当对象快结束时,会调用两次free函数,此时Member2已经是野指针(图中有X的错误标志),这个野指针指向的内存空间已经被释放掉,再次释放会报异常错误,要解决这个问题就要涉及到深拷贝了。

深拷贝

深拷贝除了拷贝其成员本身的值之外,还拷贝成员指向的动态内存区域内容,深拷贝会在堆内存中另外申请空间来储存数据。

解决的思路是在释放掉被赋值指针变量的旧指向内存时,重新对其开辟新内存,这种情况下两个结构体中指针地址不同,但是指向的内容是一致的。代码如下:

#include <stdio.h>
#include <stdlib.h>
 
typedef struct {
 char *name;
 int age;
}Member;
 
int main() {
 Member Member1;
 Member1.name = malloc(sizeof(char) * 64);
 if (NULL == Member1.name)
 {
  printf("malloc failed\n");
 }
 memset(Member1.name, 0, 64);
 //strcpy(Member1.name, "LiMing");
 snprintf(Member1.name, 64, "LiMing");
 Member1.age = 18;
 
  Member Member2;
 Member2.name = malloc(sizeof(char) * 64);
 if (NULL == Member2.name)
 {
  printf("malloc failed\n");
 }
 memset(Member2.name, 0, 64);
 //strcpy(Member2.name, "LiMing");
 snprintf(Member2.name, 64, "LiXiaoYao");
 Member2.age = 29;
 
 if (Member1.name != NULL) {
  free(Member1.name);
  Member1.name = NULL;
 }
 Member1.name = malloc(strlen(Member2.name) + 1);
 strcpy(Member1.name, Member2.name);
 
 printf("%s, %d\n", Member1.name, Member1.age);
 
 if (NULL != Member1.name) {
  free(Member1.name);
  Member1.name = NULL;
 }
 if (NULL != Member2.name) {
  free(Member2.name);
  Member2.name = NULL;
 }
 system("pause");
 return 0;
}

运行如下:

结论

使用C语言来说,深拷贝浅拷贝的概念我们不需要深究,在进行结构体拷贝的时候,结构体成员是非指针的话,那么直接赋值是没有任何问题的,建议使用这种方式,避免浅拷贝这类不易发现的错误产生。

如果成员有指针类型,我们就需要重写拷贝函数,自己定义拷贝行为了,这一点我们需要尤为注意。

到此这篇关于C语言结构体成员赋值的深拷贝与浅拷贝详解的文章就介绍到这了,更多相关C语言深拷贝 浅拷贝内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C语言结构体成员赋值的深拷贝与浅拷贝详解

本文链接: https://www.lsjlt.com/news/168801.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言结构体成员赋值的深拷贝与浅拷贝详解
    目录浅拷贝结构体中不存在指针成员变量时结构体中存在指针成员变量时深拷贝结论浅拷贝 C语言中的浅拷贝是指在拷贝过程中,对于指针型成员变量只拷贝指针本身,而不拷贝指针所指向的目标,它按字...
    99+
    2022-11-13
  • C++构造函数的类型,浅拷贝与深拷贝详解
    目录一、无参构造函数二、含参构造函数三、拷贝构造函数四、深拷贝和浅拷贝总结一、无参构造函数 1.如果没有定义构造函数,则系统自动调用此默认构造函数,且什么都不做。 2.如果用户自定义...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作