这里先简单讲一讲c中的浅拷贝与深拷贝,关于更深层使用的拷贝构造函数,深拷贝构造函数,浅拷贝构造函数等,以及其他语言的深拷贝这里就不赘述了。结构体跟类其实很类似,不管是使用或者作用域上。
浅拷贝:表层的引用,实际指向同一块内存
深拷贝:存放在不同的内存空间当中
typedef struct{
char name[20];
int age;
}student;
student stu1;
student stu2;
stu1.name="kkk";
stu1.age=20;
stu2=stu1;
printf("stu1 addr=%p, addr stu1.name=%p\n",&stu1,stu1.name);
printf("stu2 addr=%p, addr stu2.name=%p\n",&stu2,stu2.name);
调试可以发现stu1和stu2地址相同,因为二者指向的是同一块内存,如果后面调用
free(stu1);
free(stu2); 则会挂掉,因为重复释放了
至于深拷贝,可以给stu2单独分配一块空间,然后再把内容拷贝过去。
参考:
https://blog.youkuaiyun.com/q2519008/article/details/88310012
https://blog.youkuaiyun.com/sinat_35297665/article/details/78637019
浅拷贝
首先看下面这段代码:
-
# include<assert.h>
-
# include<string.h>
-
#include <stdlib.h>
-
typedef
struct Node//定义了一个结构体
-
{
-
int size;
-
char *data;
-
}S_Node;
-
int main()
-
{
-
S_Node node1;
-
node1.data = (
char *)
malloc(
sizeof(
char)*
100);
//指针所指向的地址
-
assert(node1.data !=
NULL);
-
strcpy(node1.data,
"hello world");
-
node1.size =
strlen(node1.data);
-
S_Node node2 = node1;
-
printf(
"%d, %s\n", node1.size, node1.data);
-
printf(
"%d,%s\n", node2.size, node2.data);
-
free(node1.data);
-
//free(node2.data);error重复释放
-
return
0;
-
}
运行结果为:
node2=node1;仅仅完成浅拷贝(仅会将结构体变量的size,data存储的值给node2)data指向的空间以及其存储的数据并不会拷贝,即只是拷贝了8个字节,如下图,node2.size=node1.size=11,node2.data=node1.data都保存的只是地址1000。
当free(node1.data),后free(node2.data),程序会报错。原因是free(node1.data);已经将所申请的空间释放掉了,当运行free(node2.data);就会重复释放。所以结构体一般不允许直接赋值。
深拷贝
同样分析下面这段代码:
-
# include<stdio.h>
-
# include<assert.h>
-
# include<string.h>
-
#include <stdlib.h>
-
typedef
struct Node//结构体
-
{
-
int size;
-
char *data;
-
}S_Node;
-
void CopyNode(S_Node *node3, S_Node node1)//CopyNode 函数实现结构体变量的深拷贝
-
{
-
node3->size = node1.size;
-
node3->data = (char *)malloc(node3->size + 1);//申请空间
-
assert(node3->data !=
NULL);
-
strcpy(node3->data, node1.data);
-
}
-
int main()
-
{
-
S_Node node1;
-
node1.data = (
char *)
malloc(
sizeof(
char)*
100);
-
assert(node1.data !=
NULL);
-
S_Node node3;
-
CopyNode(&node3, node1);
-
printf(
"%d, %x\n", node1.size, node1.data);
-
printf(
"%d,%x\n", node3.size, node3.data);
-
free(node1.data);
-
free(node3.data);//释放申请的空间
-
return
0;
-
}
node块空间来保存node.data的数据,并不是浅拷贝中仅仅拷贝地址。
运行结果为:
参考:
https://blog.youkuaiyun.com/cyy_0802/article/details/80374812
像稍微使用高端一些或者低层一些语言都会设置这样的地址变量可服用的情况,甚至这些还可以自由定制,但是像matlab这样的高级算法语言,则不要,全部都是容易理解与使用的值传递,虽然会带来一定的内存使用问题。