c语言如何实现结构体的深度复制
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言如何实现结构体的深度复制相关的知识,希望对你有一定的参考价值。
求助大神
使用memcpy即可, 比如你另外建立一个结构体sortbook[1000]用来保存排序结果,将book中的第i个元素赋值到sortbook的第j个元素中memcpy(&sortbook[j], &book[i], sizeof(struct book));
用这个函数需要#include <string.h>
函数原型
void *memcpy(void*dest, const void *src, size_t n);
功能
由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。
头文件
#include<string.h>
返回值
函数返回一个指向dest的指针。
说明
1.source和destin所指内存区域不能重叠,函数返回指向destin的指针。
2.与strcpy相比,memcpy并不是遇到'\0'就结束,而是一定会拷贝完n个字节。
memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;
例:
char a[100], b[50];
memcpy(b, a,sizeof(b)); //注意如用sizeof(a),会造成b的内存地址溢出。
strcpy就只能拷贝字符串了,它遇到'\0'就结束拷贝;例:
char a[100], b[50];
strcpy(a,b);
3.如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址。
//注意,source和destin都不一定是数组,任意的可读写的空间均可。
参考技术A
结构体,不像C++中的类,可以通过修改拷贝构造函数来实现深拷贝。
结构的的深拷贝,只能写一个单独的函数来实现了。
下面的是一个例子:
#include<stdio.h>#include<string.h>
struct Student
char * firstName;
int num;
;
void CreateStudent(Student * tar)
tar->firstName = new char[10];
void DeleteStudent(Student * tar)
delete tar->firstName;
void DeepCopyStudent(const Student * src, Student* tar)
strcpy(tar->firstName, src->firstName);
tar->num = src->num;
void PrintStudent(const Student * tar)
printf("%s\\n", tar->firstName);
int main()
Student *s1, *s2;
s1 = new Student();
s2 = new Student();
CreateStudent(s1);
char *name = "Hello";
strcpy(s1->firstName, name);
CreateStudent(s2);
DeepCopyStudent(s1, s2);
PrintStudent(s1);
DeleteStudent(s1);
delete s1;
PrintStudent(s2); //在删除s1之后,s2仍然可以正常输出,说明深拷贝
DeleteStudent(s2);
delete s2;
return 0;
参考技术B //如有
struct A int i; char *pc;;
//并定义
struct A st = 0, "a const string ptr" ;
//则可以用
struct A *p = (struct A *) malloc(sizeof(struct A));*p = st;
//完成复制。用
free(p);
p = NULL;
//完成释放。追问
这不是浅度复制吗
追答//如有struct A int i; char *pc;;
//并定义
struct A *st;
.........
//则可以用
struct A *p = (struct A *) malloc(sizeof(struct A));
memcpy(p,st,sizeof(st))
//完成复制。用
free(p);
p = NULL;
//完成释放。
使用memcpy呢,像上面这样 参考技术C 这个关键看结构体的数据域,只要对其中的指针类型处理即可,拷贝其内容而非其本身,这样才释放指针是才不会重复释放同一内存区域追问
大神能不能用代码举个例子
追答最简单的例子便是C的string的实现
struct CStringchar * ptr;
int size;
;
void shallowCopy(struct CString * dst, struct CString * src)
dst->size = src->size;
dst->ptr = src->ptr;
void depthCopy(struct CString * dst, struct CString * src)
if(dst->size != src->size)
dst->size = src->size;
free(dst->ptr);
dst->ptr = NULL;
dst->ptr = (char *)calloc(dst->size + 1, sizeof(char));
strcpy(dst->ptr, src->ptr);
参考技术D 弱弱的问:啥是深度复制?追问
递归复制。好像所谓不用指针。我也不清楚。
递归复制。好像所谓不用指针。我也不清楚。
在 C/C++ 中使用 ProtoBuf 进行深度复制
【中文标题】在 C/C++ 中使用 ProtoBuf 进行深度复制【英文标题】:Deep-copying with ProtoBuf in C/C++ 【发布时间】:2015-04-27 21:37:51 【问题描述】:假设我有一个指针数组,每个指针都指向结构体,这些结构体中可能又包含指向其他结构体的指针;是否可以使用 protobuf 处理序列化?如果有,怎么做?
任何帮助将不胜感激。
【问题讨论】:
"How" 是什么意思,你想解释一下,如何在 c++ 中使用 protobuf? @AlanStokes:我实际上正在为不同的项目使用两者。任何一个方面的帮助都会很棒。 @MikeMB:我希望有一个嵌套指针可能发挥作用的例子。我能找到的例子都相当琐碎。 【参考方案1】:您考虑这个问题的方式与考虑 protobuf 时需要考虑的方式相反。 Protobufs 不采用现有的数据结构并将它们序列化。它们采用序列化协议并为您创建填充的数据结构。
话虽如此,嵌套序列化非常简单:
// nested.proto
message Inner
required string value = 1;
message Outer
required Inner inner = 1;
message Pointers
repeated Outer outer = 1;
假设你已经正确编译了这个,你可以使用这个协议从外向内工作。也就是说,你从最高的结构 Pointers
开始,然后进入 Inner
对象:
Pointers pointers;
for (int i = 0; i < 10; ++i)
auto outer = pointers.add_outer();
auto inner = outer->mutable_inner();
inner->set_value(std::to_string(i));
std::stringstream stream;
pointers.SerializeToOstream(&stream);
...
Pointers parsed_pointers;
parsed_pointers.ParseFromIstream(&stream);
for (int i = 0; i < parsed_pointers.outer_size(); ++i)
std::cout << parsed_pointers.outer(i).inner().value() << std::endl;
// This prints 0, 1, 2, ..., 9 all on their own lines
可以从Inner
消息开始,但是将所有权传递给Outer
消息的方式并不简单或明显:
Inner* inner = new Inner();
inner->set_value("Hello world");
Outer outer;
outer.set_allocated_inner(inner);
调用该方法将捕获inner
指针的所有权,因此您不应该自己手动delete
。
【讨论】:
【参考方案2】:我认为还有另一种方法也很有帮助。因为.set_allocated_*(A)
有一个副作用会破坏A
。要仅从A
复制,您可以尝试.mutable_*()->CopyFrom(A)
。
【讨论】:
以上是关于c语言如何实现结构体的深度复制的主要内容,如果未能解决你的问题,请参考以下文章
深度剖析结构体@自定义类型1---结构体的声明,自引用,变量定义和初始化 + 结构体内存对齐 + 结构体传参 + 结构体实现位段