首页 > 解决方案 > 当我使用来自 stl 的 make_shared 函数时,C++ 共享指针指向错误的地址

问题描述

所以我有一个类,其中有一个 shared_ptr 声明如下

std :: shared_ptr< T > dyn_arr{ new T[ dyn_arr_max_size ], std :: default_delete< T[] >() };

这指向一些大小的动态数组。我还为它实现了一个迭代器。在这个迭代器内部有一个 ++ 重载运算符。现在当我得到

shared_ptr<T> ptr_iter= dyn_arr; 

例如,它将适用于前一个或两个元素。之后,它不能正确迭代。我还注意到以下几点:

例如我的 ptr_iter 是地址 ABDC0 for ptr_iter.get() 在开始做之后

ptr_iter = std :: make_shared<T>( *(ptr.get() + 1 ) );

或者

ptr_iter = std :: make_shared<T>( ptr.get()[1] );

ptr_iter.get()现在将指向其他地址,例如 SDBC,而不是指向 ABDC4 的整数。有人可以解释一下为什么会这样吗???

我需要能够以ptr_iter = make_shared( ptr_iter.get() + 1 );某种方式做而不是ptr_iter = make_shared( *(ptr_iter.get() + 1) );

标签: c++11templatesdynamicstlshared-ptr

解决方案


std::make_shared分配你不想要的新内存。要解决这个问题,只需使用构造函数std::shared_ptr并传递数组中元素的地址。但是,std::shared_ptr一旦引用计数下降到零,就会尝试解除分配,并且您将对数组的元素调用 delete。这就是为什么您需要传递一个什么都不做的自定义删除:

std::shared_ptr<int> ptr_iter{dyn_arr.get() + 1, [](int* pi) {}};
                                              // ^-- Custom deleter does nothing

循环中的示例:

for (int i = 0; i < 9; ++i) {
  std::shared_ptr<int> ptr_iter{dyn_arr.get() + i, [](int* pi) {}};
  std::cout << *ptr_iter.get() << std::endl;
}

但是,我强烈建议不要在您的作业之外的其他情况下这样做!


推荐阅读