将带有指针的 STD 列表复制到另一个带有指针的 STD 列表

copying std list with pointers to another std list with pointers

本文关键字:STD 列表 指针 另一个 复制      更新时间:2023-10-16

我正在尝试将指针列表的值复制到另一个指针列表中。当我删除第一个指针的分配时,值不会保留在第二个列表中。我知道这是特别因为它是一个指针列表,地址被复制而不是实际值。我想知道我将如何做到这一点。

以下是我的代码:

#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;
}

以下是输出:

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

另外,我将如何删除最后一个元素? 当我循环访问列表时,条件iterator != end阻止它,并且由于列表的性质,我无法使用<=

我经常在 std::list 或 std::vector 中使用指针来避免复制,从而提高速度。 当然,该示例使用 int 的指针,这仅对示例有意义。

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;
}

使用普通指针,使用后删除容器的内容并不难。 这取决于在列表中添加或删除元素的方式和位置。

原始拥有指针存储在 STL 容器(如std::vectorstd::list)中是错误和"泄漏">的来源(例如,如果抛出异常,分配的资源就会泄漏,因为 STL 容器的析构函数不会释放原始拥有指针)。
您应该存储或使用智能指针(如果您注意它们的生命周期,观察原始指针是可以的)。

如果您确实想在 STL 容器中存储指针,并且想要共享所有权语义,则可能需要考虑std::shared_ptr. 例如,您可以拥有std::list<std::shared_ptr<T>>(在您的情况下list<shared_ptr<int>>)。

在这种情况下,您可以执行复制操作,这将转换为引用计数操作(例如,当复制某些内容而不是深度复制时,您将获得增加的引用计数;这一切都由std::shared_ptr自动管理)。