Reputation: 103
I am trying to copy the value of a list of pointers into another list of pointers. When I delete the allocation of the first pointer the values do not remain in the second list. I know this is specifically because it is a list of pointers and the address is being copied over and not the actual value. I was wondering how I would go about doing this.
the following is my code:
#include <iostream>
#include <list>
int main(int argc, char const *argv[])
{
std::list<int*> pointer_list;
std::list<int*> int_list;
int one, two, three, four, five;
one = 1;
two = 2;
three = 3;
four = 4;
five = 5;
pointer_list.push_back(new int(one));
pointer_list.push_back(new int(two));
pointer_list.push_back(new int(three));
pointer_list.push_back(new int(four));
pointer_list.push_back(new int(five));
for (std::list<int*>::iterator iterator = pointer_list.begin(), end = pointer_list.end(); iterator != end; ++iterator)
{
std::cout << **iterator << std::endl;
}
for (std::list<int*>::iterator iterator = pointer_list.begin(), end = pointer_list.end(); iterator != end; ++iterator)
{
int_list.push_back(*iterator);
}
for (std::list<int*>::iterator iterator = pointer_list.begin(), end = pointer_list.end(); iterator != end; ++iterator)
{
delete *iterator;
}
for (std::list<int*>::iterator iterator = int_list.begin(), end = int_list.end(); iterator != end; ++iterator)
{
std::cout << "INT_LIST_AFTER DELETE: " << **iterator << std::endl;
}
for (std::list<int*>::iterator iterator = pointer_list.begin(), end = pointer_list.end(); iterator != end; ++iterator)
{
std::cout << "LIST_POINTER AFTER DELETE: " << **iterator << std::endl;
}
return 0;
}
the following is the output:
1
2
3
4
5
INT_LIST_AFTER DELETE: 1469317922
INT_LIST_AFTER DELETE: 1469317925
INT_LIST_AFTER DELETE: 1469317928
INT_LIST_AFTER DELETE: 0
INT_LIST_AFTER DELETE: 5
LIST_POINTER AFTER DELETE: 1469317922
LIST_POINTER AFTER DELETE: 1469317925
LIST_POINTER AFTER DELETE: 1469317928
LIST_POINTER AFTER DELETE: 0
LIST_POINTER AFTER DELETE: 5
Also how would I go about deleting the last element? When I iterate through the list the condition iterator != end
prevents it and I cannot use <=
because of the nature of a list.
Upvotes: 0
Views: 2739
Reputation: 105
Often I use pointers in std::list or std::vector to avoid copy which improves speed. Of course the example uses pointers of int which makes sense for exemplary only.
std::vector<int> list_int;
std::vector<int> list_int_copy;
std::vector<std::unique_ptr< int >> list_heap_unique;
std::vector<std::unique_ptr< int >> list_heap_unique_copy;
for(int i=0;i<5;i++) {
list_int.push_back(i);
//std::unique_ptr<int> ptr(new int(i));
list_heap_unique.emplace_back(new int(i));// new int(i)); // allocate object to heap memory
std::cout << i << ": orig i:" << list_int.at(i) << ", heap " << *list_heap_unique.at(i) << " ptr 0x" << (void *)list_heap_unique.at(i).get(); // << std::endl;
}
std::copy(list_int.begin(),list_int.end(), std::back_inserter(list_int_copy));
for (int val: list_int_copy) {
std::cout << "copy val int: " << val; // << std::endl;
}
std::copy(std::make_move_iterator(list_heap_unique.begin()),
std::make_move_iterator(list_heap_unique.end()),
std::back_inserter(list_heap_unique_copy));
std::vector<std::unique_ptr<int>>::iterator iter;
for (iter = list_heap_unique_copy.begin();
iter!= list_heap_unique_copy.end();
++iter)
{
int *ptr = (*iter).get();
if (ptr)
std::cout << "copy val u_ptr: " << *ptr;// << std::endl;
}
With plain pointers it isn`t so hard to delete the content of the container after use. It depends how and where you add or remove elements to the list.
Upvotes: 1
Reputation: 42964
Storing raw owning pointers in STL containers like std::vector
or std::list
is a source of bugs and "leaktrocities" (e.g. if exceptions are thrown, the allocated resources are leaked, as STL containers' destructors won't deallocate the raw owning pointers).
You should either store values, or use smart pointers (observing raw pointers are fine, if you pay attention to their lifetime).
If you really want to store pointers in STL containers, and you want a shared ownership semantic, you may want to consider std::shared_ptr
. E.g. you can have std::list<std::shared_ptr<T>>
(list<shared_ptr<int>>
in your case).
In this case you can perform copy operations, that will translate into reference count operations (e.g. when something is copied, instead of a deep-copy, you get an increased reference count; it's all automatically managed by std::shared_ptr
).
Upvotes: 0