+ 1

How can I do a copy of a pointers list? C++

I have a list of pointers like this: List<Batch*> original; I want to copy the original list to a copy, I don't want my original list be modified: List<Batch*> copy = original; But it seems it doesn't work, the information is copied into the copy list, but every change I do to my copy list, it's also seen in the original list. How can I avoid that?

14th Oct 2020, 7:26 AM
Eduardo Perez Regin
Eduardo Perez Regin - avatar
10 ответов
+ 4
That' Qt, isn't it? I'm a bit confused right now, because you earlier said deep copying sounded advanced to you, on the other hand Qt is a topic I would consider advanced, not deep copying, lol. :P Anyway, any reason the Batch class can't just hold a QList of processes instead of pointers to them? Similarly, couldn't you just write the following for main: QList<Batch> batches; QList<Batch> batchesCopy; ... for(int i = 0; i < totalBatches; ++i) { batches.push_back(Batch()); } for(int i = 0; i < totalProcesses; ++i) { Process process; ... ... batches.at(index).insertProcess(process); } Now I don't really know Qt, but the pointers seem rather unnecessary to me in this scenario. If QList works like a std::list, that should theoretically fix your problem, because now the copy constructor would produce deep copies (which doesn't work with pointers) of the objects, leading to unique lists you can manipulate independently from each other.
14th Oct 2020, 4:49 PM
Shadow
Shadow - avatar
+ 4
... That is something the copy constructor can't account for, because there could be pointers, or pointers to pointers, or any level of recursion. Therefore, while the copy constructor will again allocate new nodes, it will also copy the data over as usual. Thus, we end up with pointer assignment on the node level, resulting in the pointers stored inside the nodes pointing to the same memory as the pointers in the original list. So, could you produce a deep copy? The answer is yes, but you would have to do manually what usually is handled by the copy constructor, and allocate new batches as copies of the batches stored in the first list, which the pointers in the new list can then point to. This is further complicated by the fact that your batches have the same problem in their internal structure. Therefore, while it might be possible, I'd say it is definitely not worth the amount of work you'd end up putting into it.
16th Oct 2020, 12:08 PM
Shadow
Shadow - avatar
+ 3
That depends on your code and what you are trying to accomplish. I think it would be beneficial if you could show (some) of your code and explain your goal a bit more, because with a list of pointers, there are two scenarios that I think both don't make a lot of sense: Either you have pointers to heap-allocated memory, in which case the pointers are somewhat redundant, since the list nodes themselves are already heap-allocated and objects could be stored directly in the list. Or you have pointers to stack-allocated objects, in which case you would have to duplicate the original objects in order to get unique pointers, while pointers are typically used to avoid duplicates in the first place.
14th Oct 2020, 2:56 PM
Shadow
Shadow - avatar
+ 3
Practicing pointers is fine, but if it overcomplicates the problem, I would refrain from it. Ideally, you would choose a project where pointers are meaningful/ required, e.g. a list implementation. Speaking of lists, here's how they typically work. At the base is a pointer (head) to the heap-allocated elements (nodes), which in turn store some data and a pointer to the next element. Now, a shallow copy would only assign the head pointer of the old list to the copy list. This way, both head pointers would point to the same chain of nodes, resulting in an operation on one list to affect the other as well. To prevent this, the copy constructor instead iterates the old list and allocates new nodes while only copying the data part of the old node elements. This works fine with non-pointer types, however, pointers as data introduce the same problem we faced earlier, just one level deeper. ...
16th Oct 2020, 12:02 PM
Shadow
Shadow - avatar
+ 2
You are actually creating a copy of the list like this but due the the fact that the list contains pointers and pointers of both lists are pointing to same memory locations thus any change in that memory location will reflect in both the lists.
14th Oct 2020, 8:47 AM
Arsenic
Arsenic - avatar
+ 2
Arsenic how can I solve this? I read something about deep copying, but it's kinda advanced for me...
14th Oct 2020, 8:50 AM
Eduardo Perez Regin
Eduardo Perez Regin - avatar
+ 2
The easiest want to do this is create a new list from scratch by using the values of old list.
14th Oct 2020, 9:23 AM
Arsenic
Arsenic - avatar
+ 2
That means I will need to do everything again? :(
14th Oct 2020, 2:13 PM
Eduardo Perez Regin
Eduardo Perez Regin - avatar
+ 2
Shadow Basically I have this piece of code. https://code.sololearn.com/cmz2eDxvIuvU/#cpp I have a batch.h class where it has a QList<Process *> batches (line 15), I want to save processes (you can see what kind of information I want to save, lines 68-79) to use them later. I'm allocating memory for my batches list and processes. (201-210) and at some point in my code, I want to do a copy (218), to have a "background copy" of my original list. But any change I do to my copy list (batchesCopy) are also made into my original list (batches). I want to do any operation to my batchesCopy without affecting my origin list. I didn't think about what you say, so, allocating pointers in a list is redundant?
14th Oct 2020, 3:45 PM
Eduardo Perez Regin
Eduardo Perez Regin - avatar
+ 1
Shadow well, I'm using qt but in a very basic way haha. I could not use pointers but I wanted to practice pointers, that's why I'm using pointers 😅. You are right, pointers seems to be unnecessary here but, Doing some little research I found out that I should performed a deep copy, because using batches = batchesCopy performs a shallow copy, both lists points to the same place, that's why my original list also gets modified. I read that maybe using std:: copy could do the work but is not working for me 😥. So... A deep copy is not possible with pointers?
15th Oct 2020, 3:46 PM
Eduardo Perez Regin
Eduardo Perez Regin - avatar