-1

BDD 操作に CUDD パッケージを使用しています。DdManager と呼ばれる大きなデータ構造のコピーを作成したいと考えています。問題は、このデータ構造には内部に非常に多くのポインターがあるため、直接コピーを作成すると、それは「浅い」コピーになります (用語を使用する人もいます)。つまり、新しいコピーのポインターは、指定された同じ場所を指します元のコピーによって、だから私はそれらのいずれかを変更すると、望ましくない他のものも変更します....データ構造が非常に大きく、多くのポインタで非常に詳細であるため、手動でコピー機能を作成しようとすることは現実的ではありません他の複雑な構造にも!!! ここで説明されているベクトル ソリューションを試しましたが、ネストされた構造体とポインターが多数あり、完全に新しいコピーが必要なため、期待した結果が得られませんでした。

これが私がやりたいことのコードサンプルです:

#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;
}
4

2 に答える 2

3

あなたがしなければならないと他のことわざにもかかわらず

手作業でコピー機能を作成する

...これを解決するには、それはあなたにとって間違ったアプローチだと思います。これが理由であり、ここに提案があります。

複雑なCUDDライブラリの不可欠な部分であるCUDDddManagerオブジェクトのコピーを作成しようとしています。CUDDは、一部のオブジェクトの参照カウントを内部的に使用します(これは、ここで役立つ場合があります...)が、ddManagerオブジェクトは、ライブラリのインスタンス全体を効果的に表します。参照カウントがインスタンス間でどのように機能するかはわかりません。

CUDDライブラリとそれに関連するC++ラッパーは、ddManagerの個別のコピーを作成するために必要なコピーコンストラクターを提供していないようです。これらを追加するには、おそらく深刻な労力と、使用しようとしているライブラリの詳細な内部知識が必要になります。クライアントとして。これを行うことは可能ですが、行うのは複雑です。

代わりに、現在のBDDをファイル/ストリーム/その他に書き出してから、それをddManagerの新しいインスタンスに読み戻すことを検討します。これを支援するdddmpというライブラリがあります。

また、ddManagerクラスをコピーできないようにC++ラッパーを変更することをお勧めします。

于 2012-07-03T10:00:22.233 に答える
1

「手動でコピー関数を作成しようとするのは現実的ではありません。なぜなら、データ構造は非常に大きく、他の複雑な構造への多くのポインターも非常に詳細です!!!」

これはまさにあなたがしなければならないことです。客観的なアプローチとは、1 つの大きなすべてを行うコピー メソッドを作成しないことを意味します。代わりに、すべてのオブジェクト (構造) はそれ自体のみをコピーし、コピーするものがなくなるまでそのサブオブジェクトのコピー メソッドなどを呼び出します。

「ベクトル ソリューション」などというものはありません。ベクトルは、最小のコピー メソッドを使用した最小のオブジェクトです。

構造体とクラスに違いはないので、コピーメソッドを書くだけです。

データの構造を知っているのはあなただけなので、人類を救う (またはこのデータをコピーする) ことができるのはあなただけです。

于 2012-07-03T09:37:26.667 に答える