如何复制带有数据指针的结构?

时间:2012-07-03 09:10:41

标签: c++ pointers data-structures cudd

我正在使用CUDD包进行BDD操作。 我想在其中制作一个名为DdManager的大数据结构的副本。 问题是:这个数据结构里面有很多指针,所以当我进行直接复制时,它是一个“浅”副本(因为有些人使用这个术语)即:新副本中的指针指向同一个地方指向通过原始副本,所以当我改变其中任何一个时,我也会改变另一个不受欢迎的...... 试图手工制作复制功能是不可行的,因为数据结构非常大且非常详细,许多指针也指向其他复杂结构! 我已经尝试了here描述的向量解决方案但是我没有得到预期的结果,因为有许多嵌套结构和指针,我想要一个全新的副本。

以下是我想要做的代码示例:

#include <iostream>
#include <cstdlib>
#include <string.h>
#include <vector>
using namespace std;
struct n1
{
    int a;
    char *b;
};
struct n2
{
    int **c;
    struct n1 *xyz;
};
typedef struct
{
    vector<struct n2> x;
}X;
int main()
{
    struct n2 s1;
    s1.xyz = (struct n1*)malloc(sizeof(struct n1));
    s1.xyz->a = 3;
    s1.xyz->b = (char*)malloc(5);
    s1.xyz->b[0] = '\0';
    strcat(s1.xyz->b,"Mina");
    s1.c = (int**)malloc(5 * sizeof(int*));
    for(int i = 0; i < 5; i++)
        s1.c[i] = (int*)malloc(5 * sizeof(int));
    for(int i = 0; i < 5; i++)
        for(int j = 0 ; j < 5 ; j++)
            s1.c[i][j] = i + j;
    X struct1,struct2;
    vector<struct n2>::iterator it;
    it = struct1.x.begin();
    it = struct1.x.insert(it,s1);
    it = struct2.x.begin();
    it = struct2.x.insert(it,struct1.x[0]);
    cout<<"struct2.x[0].c[1][2]  = "<<struct2.x[0].c[1][2] <<" !"<<endl; // This is equal to 3
    (struct2.x[0].c[1][2])++; //Now it becomes 4
    cout<<"struct2.x[0].c[1][2]  = "<<struct2.x[0].c[2][2] <<" !"<<endl; //This will print 4
    cout<<"s1.c[1][2]  "<< s1.c[1][2]<<" !"<<endl; // This will also print 4 ... that's the wrong thing 
    return 0;
}

2 个答案:

答案 0 :(得分:3)

尽管有人说你必须

  

手动制作复制功能

......为了解决这个问题,我认为这对你来说是错误的。这就是原因,这是一个建议。

您正在尝试创建CUDD ddManager对象的副本,该对象是复杂CUDD库的组成部分。 CUDD在内部使用某些对象的引用计数(这可能对您有所帮助......)但是ddManager对象实际上代表了库的整个实例,而且我不知道引用计数如何跨实例工作。

CUDD库及其associated C++ wrapper似乎没有提供必要的拷贝构造函数来创建ddManager的单独副本,并且添加这些可能需要认真的努力,以及对您的库的详细内部知识只是想用作客户端。尽管可以做到这一点,但这样做很复杂。

相反,我会尝试将当前的BDD写入文件/流/其他内容,然后将其读回到ddManager的新实例中。有一个名为dddmp的库可以帮助你解决这个问题。

我还建议修改C ++包装器以生成ddManager类non-copyable

答案 1 :(得分:1)

“尝试手工制作复制功能是不可行的,因为数据结构非常大且非常详细,并且还有许多指向其他复杂结构的指针!!!”

这正是你必须要做的。 客观方法意味着您不会编写一个大的do-it-all复制方法。相反,每个对象(结构)只复制自身,然后调用它的子对象复制方法等,直到没有其他东西可以复制。

没有“矢量解决方案”这样的东西,矢量就是它最小的复制方法的最小对象。

struct和class之间没有区别,所以只需编写它们的复制方法。

只有您了解数据的结构,因此您是唯一可以拯救人类(或复制此数据)的人。