使用指针复制带有指向另一个std列表的std列表

时间:2016-11-30 18:40:48

标签: c++ pointers memory-management stl

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

以下是我的代码:

#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会阻止它,因为列表的性质,我无法使用<=

2 个答案:

答案 0 :(得分:1)

通常,我在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;
}

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

答案 1 :(得分:0)

std::vectorstd::list等STL容器中存储原始 拥有指针是错误的来源,&#34;漏洞& #34; (例如,如果抛出异常,则分配的资源被泄露,因为STL容器和析构函数不会取消分配原始拥有指针)。 您应该存储,或使用智能指针(观察原始指针很好,如果你注意它们的生命周期)。

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

在这种情况下,您可以执行复制操作,这将转换为引用计数操作(例如,复制某些内容时,而不是深层复制,您会获得更多的引用计数;它会&#39 ;全部由std::shared_ptr)自动管理。