-1

I am using the CUDD package for BDDs manipulation. I want to make a copy for a big data structure in it that is called the DdManager. The problem is : this data structure has so many pointers inside it , so when I make a direct copy it is a "shallow" copy(as some use the term) i.e. : the pointers in the new copy point to the same places pointed to by the original copy , so when I change in anyone of them I also change in the other which is undesirable .... Trying to make a copy function by hand is not feasible because the data structure is really big and very detailed with many pointer to other complex structures also !!! I have tried the vector solutions described here but I did not get the expected result because there are many nested structures and pointers and I want a completely new copy.

Here is a code sample of what I want to do :

#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;
}
Community
  • 1
  • 1

2 Answers2

3

Despite other saying that you have to

make a copy function by hand

...to solve this, I think that's the wrong approach for you. Here's why, and here's a suggestion.

You're trying to create a copy of a CUDD ddManager object, which is an integral part of the complex CUDD library. CUDD internally uses reference counts for some objects (which might help you here...) but the ddManager object effectively represents an entire instance of the library, and I've no ideas how the reference counts would work across instances.

The CUDD library and it's associated C++ wrapper doesn't seem to provide the necessary copy constructors for creating separate copies of the ddManager, and to add these would probably involve serious effort, and detailed internal knowledge of a library that you are just trying to use as a client. While it's possible to do this, it's complex thing to do.

Instead, I'd look at trying to write out the current BDD to a file/stream/whatever, and then read it back into a new instance of a ddManager. There's a library called dddmp that should help you with this.

I'd also recommend that the C++ wrapper was modified to make the ddManager class non-copyable.

Community
  • 1
  • 1
Roddy
  • 66,617
  • 42
  • 165
  • 277
  • 1
    I am now trying to use a function to transfer a BDD from a manager to another one .. this function is : DdNode * Cudd_bddTransfer( DdManager * ddSource, DdManager * ddDestination, DdNode * f) I have already made a new manager and initialized it using Cudd_Init() ... the question now ... where is the BDD root node (DdNode*) stored inside the manager structure i.e. : What is the third parameter that should be sent to this function ?? Thanks in advance ! –  Jul 03 '12 at 11:20
  • No idea. Is there such a thing as a root? Maybe you pass it any node, and it transfers all linked ones? – Roddy Jul 03 '12 at 11:58
1

"Trying to make a copy function by hand is not feasible because the data structure is really big and very detailed with many pointer to other complex structures also !!! "

This is exactly what you have to do. The objective approach means that you don't write one big do-it-all copy method. Instead, every object (structure) copies only itself, and then call it's sub-object copy methods, etc, etc until there is nothing more left to copy.

There is no such thing as "vector solution", vector is simply the smallest object with it's smallest copy method.

There is no difference between struct and class, so just write them copy methods.

Only you know the structure of your data, so you're the only One who can save the humankind (or copy this data).

Agent_L
  • 4,960
  • 28
  • 30