【问题标题】:Why does deleting a valid heap-allocated pointer give "free(): invalid pointer" error?为什么删除有效的堆分配指针会产生“free():无效指针”错误?
【发布时间】:2020-11-18 15:08:24
【问题描述】:

我是 C++ 新手,正在尝试对 shared_ptr (WIP) 做一个非常基本的实现。我试图在通过取消引用找到基础值后立即删除析构函数中的堆分配指针。虽然取消引用发生得很好,但删除 '''ref_count''' 变量会导致问题。有人可以帮忙吗? '''

#include<iostream>

template<typename T>
class shared_ptr{
 private:
  T* native_ptr_ = nullptr;
  int* ref_count_ = nullptr;

  inline void increment_count() {
    *ref_count_++;
  }

  inline void decrement_count() {
    *ref_count_--;
  }

 public:
  shared_ptr() {
    std::cout << "shared_ptr: empty constructor" << std::endl;
    native_ptr_ = nullptr;
    ref_count_ = nullptr;
  }

  shared_ptr(T* ptr) {
    std::cout << "shared_ptr: constructor" << std::endl;
    if (ptr) {
      native_ptr_ = ptr;
      ref_count_ = new int(1);
    }
  }

  ~shared_ptr() {
    std::cout << "shared_ptr: destructor" << std::endl;
    if (ref_count_) {
      decrement_count();
      if (ref_count_ && use_count() == 0) {
        std::cout << *ref_count_ << " " << *native_ptr_ << std::endl;
        delete ref_count_;
        delete native_ptr_;
        ref_count_ = nullptr;
        native_ptr_ = nullptr;
      }
    }
  }

  int use_count() const {
    if(ref_count_) {
        return *ref_count_;
    } else {
        return 0;
    }
  }
};

int main() {
  // case1
  int* temp = new int(0);
  shared_ptr<int> a1(temp);
  return 0;
}

'''

'''

shared_ptr: constructor
shared_ptr: destructor
0 0
free(): invalid pointer
Aborted (core dumped)

'''

【问题讨论】:

  • 这就是你所拥有的一切吗?这段代码不应该给你那个错误。
  • 调试指针问题时的提示:检查实际的指针值,而不是它所指向的数据。
  • @OP 除非您将 shared_ptr 的版本放在其自己的命名空间中,否则您应该将其命名为 shared_ptr 以外的其他名称。已经有一个std::shared_ptr
  • @PaulMcKenzie 我不同意,std::shared_ptr 已经在命名空间中。 using namespace std 不好,不应该使用。
  • using namespace std: 是否不好并不是重点。 C++ 程序员在代码中只看到shared_ptr 就会立即相信所指的是std::shared_ptr。无论如何,为可能与 std:: 名称冲突的名称创建命名空间是一种很好的方式。

标签: c++ shared-ptr destructor delete-operator reference-counting


【解决方案1】:

运算符优先级导致您出现问题。您实际上是在递减指针,然后推迟新地址。如果你提高警告,你会得到这样的东西:

p.cpp:35:7:   required from ‘shared_ptr<T>::~shared_ptr() [with T = int]’
p.cpp:58:26:   required from here
p.cpp:14:5: warning: value computed is not used [-Wunused-value]
   14 |     *ref_count_--;
      |     ^

您可以在递减之前添加括号以取消引用指针。

【讨论】:

  • 需要对上一条语句进行更正:ref_count 确实需要是一个指针,但是 OP 的程序只是没有实现复制构造或复制分配来自另一个共享指针。
  • @paddy - 我错过了什么吗?除非我读错了代码,否则ref_countnative_ptr 要么都是nullptr,要么都不是。可以检查native_ptr 并保存分配,对吗?
  • 很明显,其意图是创建一个共享指针习语。他们甚至表示他们的程序是 WIP。与大多数编程新手不同,他们分段实现并分阶段测试它实际上是一件好事。建议将 ref_count 更改为不适合共享指针使用的内容是一种误导,即使当前编写的代码不需要这样做。
  • @paddy - 很公平。已编辑。
  • @paddy 我刚刚做了。谢谢大家!
猜你喜欢
  • 2012-07-23
  • 1970-01-01
  • 2012-02-21
  • 1970-01-01
  • 1970-01-01
  • 2016-10-17
  • 2018-06-18
  • 2018-09-17
  • 1970-01-01
相关资源
最近更新 更多