2

so I have a structure like

struct GetResultStructure
{
  int length;
  char* ptr;
};

I need a way to make a full copy of it meaning I need a copy to have a structure with new ptr poinnting on to copy of data I had in original structure. Is It any how possible? I mean any structure I have which contains ptrs will have some fields with its lengths I need a function that would copy my structure coping all ptrs and data they point to by given array of lengthes... Any cool boost function for it? Or any way how to create such function?

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
Rella
  • 65,003
  • 109
  • 363
  • 636

5 Answers5

7

For the specific scenario you describe, use a std::vector or some other sequence container. If you do so, then simply copying objects of type GetResultStructure will make copies of the pointed-to data as well:

struct GetResultStructure {
    std::vector<char> data;
};

GetResultStructure a = GetData();
GetResultStructure b = a; // a and b have distinct, equivalent data vectors

In general, when you do need to implement this yourself, you do so by implementing a copy constructor and a copy assignment operator. The easiest way to do that is to use the copy-and-swap idiom, covered in great detail in What is the copy-and-swap idiom?

Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977
2

It's pretty much up to you to implement that. Normally you want to do it as a copy constructor so you only have to do it in one place. Unfortunately, there's no real magic to avoid telling the computer about how to copy your structure.

Of course, that only applies if your structure really is substantially different from something that's already written. The one you've given looks a lot like a string or (possibly) vector. Unless you really need to implement something new, you're probably better off just using one of those that's already provided.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
2

Both a copy constructor and assignment operator should be implemented (in the way stated above). A technique which may aid in this process, however, is using a dereference operator (*) when copying pointer data. This will copy the pointer data rather than the memory locations. If you do ptr1 = ptr2 it simply sets the memory location of ptr1 to ptr2 which is why we dereference.

For instance, I'll just show a quick example for a copy constructor:

GetResultStructure(const GetResultStructure& other)
    : length(other.length), ptr(new char[length]) // <--- VERY _important_ - initialization of pointer
{
    // Alternatively, put your initialization here like so:
    // ptr = new char[length];
    for(int i=0;i<length;++i)
    {
        ptr[i]  = new char;
        *ptr[i] = *other.ptr[i]; // Copy the values - not the memory locations
    }
}

And then obviously be sure to clean up in your destructor to prevent memory leaks.

Regards,
Dennis M.

RageD
  • 6,693
  • 4
  • 30
  • 37
  • 1
    The ptr probably points to an *array* instead of a single item (you even acknowledge this in how you initialize ptr), yet the above code would only copies the first item in that array. – Fred Nurk Jan 31 '11 at 07:02
  • `ptr[i] = new char;` is incorrect. That said, there is an algorithm that performs this operation, and `std::copy(other.ptr, other.ptr + other.length, ptr);` is much more terse. While it is generally preferable to initialize members in the initializer list, it is recommended _not_ to perform dynamic allocation if you are assigning the result to a raw pointer to avoid potential memory leaks when exceptions occur. – James McNellis Jan 31 '11 at 15:28
1
GetResultStructure doCopy(GetResultStructure const& copy) {
  GetResultStructure newstruct;
  newstruct.length = copy.length;
  newstruct.ptr = new char[newstruct.length];
  memcpy(newstruct.ptr, copy.ptr, newstruct.length*sizeof(char));
  return newstruct;
}

Should be simple. Yes, the sizeof(char) isn't really necessary, but there to show what to do for other data types.

Alexander Rafferty
  • 6,134
  • 4
  • 33
  • 55
  • Why a function instead of a copy ctor? – Fred Nurk Jan 31 '11 at 07:00
  • While `memcpy` will work for an array of `char`, it won't work for an array of any non-POD type. `std::copy` is almost always preferable because it actually copies objects, not just raw bytes in memory. – James McNellis Jan 31 '11 at 15:25
1

Since you tagged it as C++: Write a copy constructor and an assignment operator, within which you implement your deep copy code:

struct GetResultStructure
{
    GetResultStructure(const GetResultStructure& other)
    {
        // Deep copy code in here   
    }
    GetResultStructure& operator=(const GetResultStructure& other)
    {
        if (this != &other) {
            // Deep copy code in here
        }
        return *this
    }
    int length;
    char* ptr;
};
lx.
  • 2,317
  • 1
  • 22
  • 32
  • 1
    I actually love your answer the most. But I have a question for you -how in such example to implement "Deep copy code"? – Rella Jan 31 '11 at 06:47
  • in your case i'd assume that it looks something like this: `length = other.length; ptr = new char[length]; memcpy(ptr, other.ptr, length);`. And you have to delete your old ptr data in your "operator=". Sorry, haven't got much time right now to explain further :\ – lx. Jan 31 '11 at 09:22