【问题标题】:Vector of pointers to dynamically-allocated objects: what could go wrong?指向动态分配对象的指针向量:会出现什么问题?
【发布时间】:2011-10-28 07:27:36
【问题描述】:

我在发帖之前查看了这个帖子:How to avoid memory leaks when using a vector of pointers to dynamically allocated objects in C++?

基本上,我有一些指向动态分配对象的指针向量:

vector<MyType*> a;
a.push_back(new MyType());

这些向量是我正在编写的几个类的私有实例变量,动态分配的对象通过遍历向量并在每个指针上调用delete 在类的析构函数中被销毁。

大多数时候一切正常,但每隔一段时间,这些向量之一中的指针就会变得无效,并在我的代码尝试使用它时导致segfault。我无法弄清楚为什么这些指针偶尔会中断。

动态分配的对象的地址会发生变化,导致指针失效,有什么原因吗?

如有必要,我可以尝试发布实际代码。

编辑:

好的,我这里有很多事情要做。有两个自定义类:VisaLaneVisaResourceVisaLane 包含一个指向使用 new VisaResource() 创建的 VisaResources 的指针的 vector&lt;VisaResource*&gt;

每个VisaLane 也是使用new VisaLane() 创建的,其指针存储在vector&lt;VisaLane*&gt; 中。

这是指针如何损坏的一个示例。向量中的第 0 项具有不可访问的成员:

resources_  <3 items>   std::vector<VisaResource*>
    [0]     VisaResource
        function_   <not accessible>    std::string
        name_   <not accessible>    std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  6998928 uint
    [1]     VisaResource
        function_   "lane_clksel"   std::string
        name_   "m1_lane0_clksel"   std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  0   uint
    [2]     VisaResource
        function_   "lane_bypass"   std::string
        name_   "m1_lane0_bypass"   std::string
        state_  VisaResource::FREE  VisaResource::VisaResourceState
        value_  0   uint
visa_res_itr        __gnu_cxx::__normal_iterator<VisaResource**, std::vector<VisaResource*>>

【问题讨论】:

  • 我应该补充一点,我会在 boost 库中使用漂亮的自动指针,但我的客户只想要使用标准库的代码,并且特别要求不要使用 boost 代码。相信我,我试图以其他方式说服他们,但他们不想让步。
  • 可以选择 TR1 吗?大多数半最新的编译器都附带了它,您可以制作一个 std::tr1::shared_ptrs 的容器,这应该可以解决您的问题。
  • 嫌疑人可能包括地址错误的写入和内存覆盖。

标签: c++ pointers vector memory-management


【解决方案1】:

您根本不应该使用原始指针,避免这种情况的最佳方法是使用 智能指针Unique_ptr 如果您不共享您的矢量内容 shared_ptr 如果容器元素正在跨多个实体共享。

使用智能指针很可能会帮助您解决问题。

除此之外没有看到源代码,我们无法评论真正出了什么问题。

【讨论】:

  • @Andrew Wiens:几乎所有您可能需要的东西(根据上述答案中提到的需要)是:std::tr1::shared_ptrstd::unique_ptr,但请远离auto_ptr,它不是为与 STl 容器一起使用而设计的。
  • 它们必须是可复制的才能与 STL 容器一起使用。 std::auto_ptr 无法使用,因为它在分配时交换所有权,因此无法复制。
  • @Andrew:根据标准,STL 容器支持所有推荐的 smart_pointers。注意auto_ptr,最老的smart_pointer。从 C++0x 开始已弃用,容器不支持!
【解决方案2】:

如果您的编译器支持 C++0x,您可以为 STL 容器创建自己的可复制引用计数智能指针类或使用std::unique_ptr。如果它稍微旧一点,你可能在 std::tr1 命名空间中有一些东西。

或者考虑std::vector&lt;MyType&gt;,因为该容器无论如何都会在堆上连续分配,并将为您管理内存。不惜一切代价避免使用原始指针。

【讨论】:

    猜你喜欢
    • 2021-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2011-05-23
    • 2011-12-19
    相关资源
    最近更新 更多