当前位置: 首页 > news >正文

C语言中结构体的深拷贝与浅拷贝

在C语言开发中,我们有时会碰到针对结构体的拷贝,对于结构体的拷贝通常分为两种:深拷贝与浅拷贝。

浅拷贝:直接复制结构体所有成员的值,如果成员是指针,则复制的是指针本身(内存地址),而不是指针指向的数据。

结果:含指针成员拷贝后,两个结构体中的指针成员指向同一块内存地址。

深拷贝:不仅复制结构体本身,如果成员是指针,还会为指针成员指向数据分配独立内存,并复制数据内容。

结果:含指针成员拷贝后,两个结构体中的指针成员内存地址独立。

以下将使用一个简洁的代码来传递结构体深拷贝与浅拷贝的区别。

1.使用浅拷贝的方式来观察成员的变化

image

 浅拷贝下:指针成员共享同一块内存地址,修改一个,就会影响到另外一个。

释放内存空间时,仅需释放1个就行。

image

 

2.使用深拷贝的方式来观察成员的变化

image

  深拷贝下:指针成员独立同一块内存地址,修改一个,不会影响到另外一个。

 释放内存空间时,释放2个。

image

 

深拷贝与浅拷贝的对比表格:

参考代码如下:

 1 #define _CRT_SECURE_NO_WARNINGS  //屏蔽警告 VS编译器对strcpy检查报错
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 //结构体的深拷贝和浅拷贝
 6 //浅拷贝:直接复制结构体所有成员的值,若成员是指针,则复制内存地址。
 7 //深拷贝:不仅复制结构体本身,还为指针成员指向的数据分配独立的内存,并复制数据内容。
 8 
 9 //定义一个基础结构体
10 typedef struct
11 {
12     int age;
13     char* name;
14 } SomeOne;
15 
16 //深拷贝函数
17 void deepCopy(SomeOne *dest, SomeOne *src)
18 {
19     dest->age = src->age;
20     dest->name = (char*)malloc(strlen(src->name) + 1);
21     strcpy(dest->name, src->name);
22 }
23 
24 int main()
25 {
26     //浅拷贝
27     SomeOne  P1;
28     P1.age = 21;
29     P1.name = (char*)malloc(10);
30 
31     strcpy(P1.name, "Tom");
32 
33     SomeOne P2 = P1; //直接将P1拷贝至P2
34 
35     printf("P1.age = %d ,P2.name = %d\n", P1.age, P2.age);
36     printf("P1.name = %s ,P2.name = %s\n", P1.name, P2.name);
37     printf("P1.name = %p ,P2.name = %p\n", P1.name, P2.name);
38 
39     P2.age = 24;
40     printf("P1.age = %d ,P2.name = %d\n", P1.age, P2.age);
41     printf("P1.name = %s ,P2.name = %s\n", P1.name, P2.name);
42     printf("P1.name = %p ,P2.name = %p\n", P1.name, P2.name);
43 
44     //两个指针共享同一个地址,修改一个,则会影响另一个
45     //浅拷贝:复制指针
46     strcpy(P2.name, "Alex");
47     printf("P1.age = %d ,P2.name = %d\n", P1.age, P2.age);
48     printf("P1.name = %s ,P2.name = %s\n", P1.name, P2.name);
49     printf("P1.name = %p ,P2.name = %p\n", P1.name, P2.name);
50 
51     free(P1.name); 
52     //free(P2.name); 仅释放一个内存地址即可
53 
54 
55     //深拷贝
56     SomeOne  P3;
57     P3.age = 30;
58     P3.name = (char*)malloc(10);
59 
60     strcpy(P3.name, "Jerry");
61 
62     SomeOne  P4;
63     deepCopy(&P4, &P3);
64 
65     printf("P3.age = %d ,P4.name = %d\n", P3.age, P4.age);
66     printf("P3.name = %s ,P4.name = %s\n", P3.name, P4.name);
67     printf("P3.name = %p ,P4.name = %p\n", P3.name, P4.name);
68 
69     //深拷贝是复制指针指向的内容
70     P4.age = 33;
71     printf("P3.age = %d ,P4.name = %d\n", P3.age, P4.age);
72     printf("P3.name = %s ,P4.name = %s\n", P3.name, P4.name);
73     printf("P3.name = %p ,P4.name = %p\n", P3.name, P4.name);
74 
75 
76     strcpy(P4.name, "Helen");
77     printf("P3.age = %d ,P4.name = %d\n", P3.age, P4.age);
78     printf("P3.name = %s ,P4.name = %s\n", P3.name, P4.name);
79     printf("P3.name = %p ,P4.name = %p\n", P3.name, P4.name);
80 
81     //两个独立的内存都需要释放
82     free(P3.name);
83     free(P4.name); 
84     return 0;
85 }

 


对比

浅拷贝

深拷贝

指针处理

复制指针值,共享数据

复制指针的指向的数据,独立数据

内存管理

易产生悬空指针、重复释放

需要手动管理

性能

快(只复制结构体本身)

慢(复制数据和分配内存)

适用场景

结构体中无指针成员

结构体含有指针成员,需要独立副本

意义

简单拷贝方式

浅拷贝的补充和扩展(指针成员)

http://www.jsqmd.com/news/429292/

相关文章:

  • 最长公共子序列(一)
  • P2580 于是他错误的点名开始了
  • DVWA 靶场实验报告 (Low Level)
  • 2026多模态情感识别深度解析(非常详细),ComP跨模态提示全攻略,收藏这一篇就够了!
  • 2026年ASOC SCI2区TOP,基于树状网络的多目标人工蜂群学习算法在无人机中的应用,深度解析+性能实测
  • 哪些是可以提供市场调查服务的网站:头部机构汇总(防坑必看) - 品牌排行榜
  • Agent Lightning实战入门教程(非常详细),AI智能体自我进化从入门到精通,收藏这一篇就够了!
  • 修复Windows蓝屏问题
  • OpenClaw深度拆解教程(非常详细),下一代本地Agent操作系统全解析,收藏这一篇就够了!
  • 大数据领域Spark的调优经验分享
  • Jbd8:总结
  • 最短路 - ## 采购特价商品
  • RAG文本分块全攻略(非常详细),七种主流策略从入门到精通,收藏这一篇就够了!
  • LLM-RL训练框架入门基础教程(非常详细),3大流派+6大框架从入门到精通,收藏这一篇就够了!
  • Jbd3:HDFS
  • pikachu靶场——Cross-Site Scripting-4 XSS盲打与过滤(Kali系统)
  • 动态树LCT
  • 多模态大模型 | 利用词嵌入多模态语义知识对齐以增强图片-文本匹配
  • Jbd2:Hadoop
  • 云服务器配置 docker-spark
  • OpenKylin够牛,能远程操作的OpenKylin更牛!
  • go-zero的kafka配置
  • 2026年充电桩厂家全场景选型指南:汽车充电桩/重卡充电桩/船舶充电桩/两轮车充电桩 - 资讯焦点
  • Jbd0:前言 Jbd1:概述
  • 最短路 - ## 邮递员送信
  • 2026海外求职机构哪家成功率高:名企资源+导师实力测评(必看) - 品牌排行榜
  • 2026年2月中国网站建设公司推荐榜:十大靠谱口碑供应商 - 资讯焦点
  • 2026年3月京东E卡回收平台精选榜单|收券宝为何成为行业标杆 - 资讯焦点
  • 2026年3月京东E卡回收平台深度测评|收券宝凭三大优势登顶榜首 - 资讯焦点
  • leetcode172.阶乘后的零