结构体知识梳理4-浅拷贝深拷贝

应用场景分析,我们希望对一个学生的信息做备份

代码一

typedef struct student{
	int num;
	int age;
	char name[10];
}s_stu,*p_stu;
//stu1  stu2 有独立的内存空间,存储 num  age  name
s_stu stu1;
s_stu stu2;
stu1.num = 1;
stu1.age = 1;
strcpy(stu1.name,"lilei");
//以下做的是memcpy(&stu2,&stu1,sizeof(s_stu))
stu2 = stu1;
printf("stu2.num = %d",stu2.num);
printf("stu2.age = %d",stu2.age);
printf("stu2.name = %s",stu2.name);

stu1 和stu2分别有两个char  name[10]数组存储字符串

以上代码,stu1 ,stu2 分别存储一份学生的信息,可以实现学生信息的备份

我们画内存图如下:

对于以上代码来说,用数组存储姓名,这样字符串的最大长度已经固定,如果字符串长度超过数组长度,则会出现问题。

代码二

因此我们需要根据字符串的长度来动态分配内存空间,我们定义以下结构体

typedef struct student{
	int num;
	int age;
	char *name;
}s_stu,*p_stu;

我们写以下测试代码

char *buff = "lilei";//需要存储的学生的名字
s_stu stu1;
s_stu stu2;

stu1.num = 1;
stu1.age = 1;
stu1.name = malloc(strlen(buff))+1;//根据字符窜长度来分配相应内存。
strcpy(stu1.name,buff);

//以下做的是memcpy(&stu2,&stu1,sizeof(s_stu))
stu2 = stu1;
printf("stu2.num = %d",stu2.num);
printf("stu2.age = %d",stu2.age);
printf("stu2.name = %s",stu2.name);
//到这里打印没有问题。

到此,我们画内存图如下:

注意这里并没有把 名字复制一份存储下来,而只是stu2.name 指针 和 stu1.name 指针存储了同一个地址,如果一旦 free(stu1.name),则这时候stu2.name也不能使用了,并没有把字符串复制存储下来,这种现象叫做浅拷贝。

我们希望对学生的有效信息有两份,因此内存图应该是如下:

这种现象叫做深拷贝。

根据以上需求我们写代码如下

//假定能够复制的前提是 src 已经存储了学生信息
void stucpy(p_stu dest,const p_stu src)
{
	int len = 0;
	//检查dest ,src 不为null
	//检查src->name 不为null
	len = strlen(src->name)+1;
	//这里为什么要释放?
	if(dest->name!=NULL)
	{
		free(dest->name);
	}
	dest->name = (char*)malloc(len);
	//检查dest->name 不为null
	strcpy(dest->name,src->name);
	dest->num = src->num;
	dest->age = src->age;

}

以上代码请大家分析补充完整。

结构体知识梳理4-浅拷贝深拷贝

时间: 2024-11-06 09:49:59

结构体知识梳理4-浅拷贝深拷贝的相关文章

结构体语法梳理2-指针与一维数组

结构体指针与结构体数组 1.1 指针复习 对于指针的理解,我们一方面从语法层面上理解,一方面编译器角度理解会发生什么事情. type  *p = value; p+i   的结果是 value+sizeof(type)*i 对于指针变量p ,*前面的type决定了 如何通过p存储的地址去访问内存. 比如 int  *p1 = 0x10; char *p2 = 0x10; double  *p3 = 0x10; *p1 从 0x10地址处访问四个字节,并且把这四个字节的数据当int类型来看. *p

指针和结构体知识学习

这一周主要学习了C语言中的最灵活的技巧 --指针.指针也是一个变量,它有自己的地址也有指向的地址,一般来说我们更关注的是指针指向的地址.指针的指向可以是整数.浮点数.字符.数组,同样的也可以是一个函数. 指针的基本操作有赋值.求值.取指针地址.将一个整数指针加给指针,增加指针的值.减小指针的值和求差值.如下程序所示: 1 /*ptr_ops.c - 指针操作*/ 2 #include <stdio.h> 3 int main() 4 { 5 int urn[5] = {100, 200, 30

你必须知道的指针基础-6.内存的初始化及结构体的使用

一.内存的使用 1.1 你创建的内存区域可能是脏的 当我们创建一个内存区域的时候,内存中的数据可能是乱七八糟的(可能是其他代码用过后遗留的数据),如下面一段代码: int main(int argc, char *argv[]) { // 下面申请的20个字节的内存有可能被别人用过 char chs[20]; // 这个代码打印出来的可能就是乱码,因为printf的%s是“打印一直遇到'\0'”. printf("%s\n",chs); return 0; } 其运行结果是如下图所示的

HDU - 1789 Doing Homework again(贪心) ~~~学了一波sort对结构体排序

题目中因为天数和分数是对应的,所以我们使用一个结构体来存分数和截止如期. 一开始做这道题的时候,很自然的就想到对天数排序,然后天数一样的分数从大到小排序,最后WA了之后才发现没有做到"舍小取大"的贪心.所以改变一下策略,对分数排序,如果分数一样的话,时间从小到大排序(因为我们的目的就是先做分多的作业,所以分数一样的得放到前几天去做). (具体sort排结构体知识见代码里面,其实也可以写两次for来排序): 思路:排好序之后,从小到大遍历,每找到一个分数,去寻找对应的天数到第一天中有没有

C语言中结构体赋值问题的讨论(转载)

今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言中结构体赋值的问题吧: 结构体直接赋值的实现 下面是一个实例: #include <stdio.h> struct Foo { char a; int b; double c; }foo1, foo2; //define two structs with three different field

struct结构体基础知识

/* ============================================================================ Name : TestStruct.c Author : lf Version : Copyright : Your copyright notice Description : struct结构体基础知识 ==================================================================

结构体的基础知识及存储分配

一.结构体的访问 1.结构体成员的的直接访问,如下结构体: struct  A{ int a; long *b; char c[20]; }; struct A   com; 结构体成员通过操作符"."访问,表达式com.a的结果是个数组名,可以把它使用在任何可以使用数组名的地方,com.a[4],将选择一个数组元素. 2.结构体成员的间接访问 struct A *p; 可以使用(*p).a访问结构体成员,但这种形式有点不简洁所以使用操作符"->"来访问结构体

c语言结构体小知识

引自:http://c.biancheng.net/cpp/html/88.html 结构体在内存中是连续存储的 struct stu{ char *name; //姓名 int num; //学号 char sex; //性别 float score; //成绩 } stu1, stu2 = { "Tom", 10, 'M', 90 }; 不过整体赋值仅限于上面这样的情况,也就是定义结构体的同时声明变量.下面的写法是错误的: stu2 = { "Tom", 10,

swift:入门知识之枚举和结构体

枚举: swift中的枚举有些类似于类这个概念,它有自己的属性,也可以有自己的方法 枚举中的成员有原始值和实际值之分,原始值用来枚举成员的排序次序,默认从0开始 枚举出来的成员值就是实际值 可以通过toRaw和fromRaw函数转换原始值和枚举值 也可以使用字符处或浮点数作为枚举的原始值 具体举例如下: //给扑克牌内容声明一个枚举(A.2.3.4.5.6.7.8.9.10.J.Q.K) enum Rank:Int{ case Ace case Two,Three,Four,Five,Six,S