Clone a struct without copying the memory address

Asked

Viewed 390 times

1

I need to copy the struct problema1 to the struct problema2 , but to do the way it is in the program below , when I change the struct problema2 also be changing the struct problema1. The way I did it by copying the reference, I wanted to copy without reference, but I don’t know how you do it.

void __fastcall TForm1::Button1Click(TObject *Sender)
{

 struct Tproblem
   {
    TList *Lista;
    float x;
    };

  typedef struct Tproblem Problem;
  Problem *Problema1 ,*Problema2;
  int *x;
  Problema1 = new Problem;
  Problema1->Lista = new TList;
  for( int i = 0 ; i<10; i++)
    {
       x = new int ;
       *x = i;
       Problema1->Lista->Add(x) ;
     }



   Problema2 = new Problem;
    Problema2 = Problema1;// aki eu copia a estrutura


     for( int i = 0 ; i<Problema1->Lista->Count ;i++)
    {
      x = (int*)Problema1->Lista->Items[i];
      ListBox1->Items->Strings[i]=IntToStr(*x);

1 answer

2


This code is copying the pointer, carrying the code has two variables pointing to the same object, so changing one changes what is pointed at the other. What you need is to create a new object and point to it. This can be done with memcpy(). Something like that:

memcpy(Problema2, Problema1, sizeof(Problema1));

I put in the Github for future reference.

There are better ways to solve this, but then you’d need to tamper with all the code.

  • First of all thank you for the quick return , I changed the code , using the function memcpy() but deleting an item from problem 2 continues deleting an item from problem 1

  • This should not happen, so they have another problem and should ask another question showing what they did. You should not modify the question. So you invalidate the answer. What I can tell you is that you will have to do the same with the member Lista of the structure. I’m gonna point out what I’ve said before, this is not the right way to do this, but I can’t rewrite all the code for you, and I don’t know if I’d want this.

  • With this it will copy the pointer from the list, it should create a memcpy for the list as well, no?

  • @Joãosobral this, whenever you have a pointer, if you copy the pointer is just copying a reference to the data. When you want to copy the data you have to use some technique of copying the memory where it is. This is one of them. In fact I’ll repeat, this is not how you do it in C++.

  • If the copy of this struct will be frequent you can implement a "copy" method in this struct, in order to automate the copy of the list and the struct itself, possibly using memcpy exemplified by bigown.

  • @mustache I’ll ask another question posting what I did , also implementing memcpy function for my list. thanks!

  • @bigown Unfortunately this solution does not solve the problem and still recommends the use of memcpy to copy structures when the person is using C++. The correct and simplest is to use the copy operator, either the default or one defined by the user when the default is not correct, since this ensures that the members' copies are made according to the intention of the person who created the types, the exception being pointers. In that case, use should be made of Problema2 = new Problem(*Problema1); and declare a copy constructor that correctly copies the list within the structure.

  • @Tiagogomes I do not recommend no, I say it is not ideal. But for this specific code I thought it was the best solution. You can disagree, but you can’t say you’re wrong. He said he’d post another question, so I’d show you another way. The whole code is too bad to provide a sophisticated solution. Create a copy constructor in something that is being declared within a method, do not think exaggerated not? Maybe you don’t understand what this resource is for.

  • @Bigown I do not think exaggerated, that is the function of a copy builder. While not wanting to be ideal, your solution is ignoring what the language itself recommends to use a C function that ignores all the extra that even the default copy constructor can do when needed. In addition, your solution is not simpler than using the standard builder since replace memcpy(Problema2, Problema1, sizeof(Problema1)) for Problema2 = new Problem(*Problema1) would have the same practical effect in this case but would use the functionality recommended by the language.

  • But you will have to write the copy builder to use once. I think exaggerate.

  • He’ll have to write the copy code anyway, either inside a copy constructor or be dropped in the middle of the function, then why not write to the copy builder which is where the language recommends and never worry about it again if for some reason it needs to copy it again ?

  • Recommendations are called that, because you have to analyze the context, in this there is no need. Following recommendations blindly serves no purpose. If you had given me a plausible reason I would change the answer. What happens here is a difference of culture. You follow recommendations, I follow what is most practical for the specific situation. In other situations I would do what you are talking about. If one day he has to change (it does not seem to be the case, after all it is only an exercise) he will have to change the code more broadly, as I put in the answer. I met his need and guided him right

  • Yes, I agree with your pragmatism but I believe that in this case it makes no sense for the simple fact that it is not a simpler or more correct solution than the solution chosen by the language itself. As stated in the other comment, your line of code in the reply can be replaced, and even by removing another line, by a line of code that has the same effect and size: Problema2 = new Problem(*Problema1). I do not see what is the plausible reason or the advantage of using an alternative solution proposed by the language itself in this case, especially when answering questions of beginners.

Show 8 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.