结构体的深层复制与删除
各位好!
以前是做JAVA的,最近做了一个C的项目,有一个问题困扰了我很久,想请教一下各位C高手.
struct {
structA* a;
} testStruct;
struct {
structB* b;
} structA;
struct {
int charLen;
char* charA;
} structB;
在结构体中,定义的元素都是指针型或者int型,之所以这样做,是因为预先知道每个结构体的长度(每个元素都是占4位),到时候好分配内存空间.但存在一些问题:
1,我想完完全全的复制一个testStruct做为一个副本,但仅仅memcpy testStruct应该是不够的.因为它底层的内容还是没有变.是不是这样?如果是这样,那怎么做才能达到效果?深度拷贝?
2,我想彻底释放testStruct这块内存,如果仅仅释放testStruct应该也达不到效果,因为那仅仅是释放了testStruct所对应的一个地址,testStruct内部没有被释放。请问想要把testStruct彻底释放,有什么好办法吗,难到也要深度释放?
不知道大家有没有遇到过这样的问题,期待大家的回答,感激!!
[解决办法]
1,我想完完全全的复制一个testStruct做为一个副本,但仅仅memcpy testStruct应该是不够的.因为它底层的内容还是没有变.是不是这样?如果是这样,那怎么做才能达到效果?深度拷贝?
==============
是这样的,自己定制深度拷贝
2,我想彻底释放testStruct这块内存,如果仅仅释放testStruct应该也达不到效果,因为那仅仅是释放了testStruct所对应的一个地址,testStruct内部没有被释放。请问想要把testStruct彻底释放,有什么好办法吗,难到也要深度释放?
还是自己定制删除操作。
如果你是用C的话,自己定制拷贝和释放,
C++的话,可以定义接口在结构体中
[解决办法]
结构体和类一样可以拥有构造函数析构函数,还有拷贝构造函数
并且可以重载=号
[解决办法]
用指针,拿malloc分配空间,用直接赋值的方式复制,不要用memcpy(即使用也要用sizeof(structX))做大小)。
如有
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;
完成释放。
[解决办法]
另外,sss_free与akirya说的都是C++,不是C。
[解决办法]
其实这个问题换个角度来看就很简单了。。。
你定义的不是一个简单的类型,而是更高级的一个数据结构
所以你对它的操作必须按照数据结构的那一套来
[解决办法]
呵呵 习惯了写C++
那你可以提供一系列的函数进行同样的操作
copystruct(struct testStruct* src,struct testStruct **de)
{
*des = (testStruct*)malloc(sizeof(struct testStruct));
(*des)-> a = (structA*)malloc(sizeof(struct structA) );
......
//这样做一层一层的做下去
}
释放内存的时候也一层一层的释放.
[解决办法]
我想可以通过重载(定制)copy构造函数,赋值构造函数以及析构函数来实现。
for example:
struct A
{
int m_nInt;
}
struct AA
{
A * m_pA;
//Copy constructor
AA(A & refA)
{
ConstructeSelf(refA);
}
//Assign constructor
AA & operator = (A & refA)
{
ConstructeSelf(refA);
return this;
}
~AA()
{
if (m_pA) delete m_pA;
}
private:
void ConstructeSelf(A & refA)
{
Destructe();
m_pA = new AA(refA);
}
void Destructe()
{
if (m_pA)
{
delete m_pA;
m_pA = NULL;
}
}
}
[解决办法]
1,我想完完全全的复制一个testStruct做为一个副本,但仅仅memcpy testStruct应该是不够的.因为它底层的内容还是没有变.是不是这样?如果是这样,那怎么做才能达到效果?深度拷贝?
================================================
为目标结构内的各级指针分配空间后,完全可以memcpy(des,src,sizeof(testStruct))啊。
2,我想彻底释放testStruct这块内存,如果仅仅释放testStruct应该也达不到效果,因为那仅仅是释放了testStruct所对应的一个地址,testStruct内部没有被释放。请问想要把testStruct彻底释放,有什么好办法吗,难到也要深度释放?
===============================================
释放时候,当然要一级级的释放,先释放最里面指针的空间,然后外层,否则会引起内存泄露...
[解决办法]
而且向 struct A{ struct *B b;....}; struct B { struct *C c;.....}
这样的,如果大小已经知道了的话,最好还是一起分配
struct A * ap = (struct A*)malloc( sizeof(struct A) + sizeof(struct B) + sizeof(struct C));
ap-> b = (struct B*)(ap + 1);
ap-> b-> c = (struct C*)(ap-> b + 1);
释放也只释放一次
[解决办法]
typedef struct
{
int charLen;
char* charA;
} structB;
typedef struct
{
structB* b;
} structA;
typedef struct
{
structA* a;
} testStruct;
structB b;
structA a;
testStruct *des,src;
//des.
int main()
{
char *p= "test ";
b.charA=p;
b.charLen=strlen(p);
a.b=&b;
src.a=&a;
printf( "%s\n ",src.a-> b-> charA);
/* alloc */
des=(testStruct*)malloc(sizeof(testStruct));
des-> a=(structA*)malloc(sizeof(structA));
des-> a-> b=(structB*)malloc(sizeof(structB));
des-> a-> b-> charA=(char*)malloc(sizeof(p));
/* copy */
memcpy(des,&src,sizeof(testStruct));
printf( "%s\n ",des-> a-> b-> charA);
/* free */
free(des-> a-> b-> charA);
free(des-> a-> b);
free(des-> a);
free(des);
return 0;
}