从原始指针到std::shared_ptr

From raw pointers to std::shared_ptr

本文关键字:shared ptr std 原始 指针      更新时间:2023-10-16

我的项目中有这两个功能:

char* V8StringToChar(v8::Handle<v8::String> str);
char* V8StringToChar(v8::Local<v8::Value> val);

我将它们转换为:

template <class T>
class ArrayDeleter {
public:
    void operator () (T* d) const
    { delete [] d; }
};
std::shared_ptr<char> V8StringToChar(v8::Handle<v8::String> str);
std::shared_ptr<char> V8StringToChar(v8::Local<v8::Value> val);

机身为

std::shared_ptr<char> V8StringToChar(Handle<String> str) {
  int len = str->Utf8Length();
  char* buf = new char[len + 1];
  str->WriteUtf8(buf, len + 1);
  return std::shared_ptr<char>(buf, ArrayDeleter<char>());
}
std::shared_ptr<char> V8StringToChar(Local<Value> val) {
  return V8StringToChar(val->ToString());
}

以及它们对CCD_ 1的每次使用。

它的结构非常完美。

它会导致运行时错误。

有没有这种情况可能会失败?请提供一些好的解决方案?

而不是

(&*V8StringToChar(whatever))

你本可以写:

V8StringToChar(whatever).get()

但两者都可能是错误的,在某些情况下肯定会失败。

这样做会创建一个新的缓冲区,将其作为shared_ptr返回,获取缓冲区的地址,然后shared_ptr超出范围,缓冲区被删除,留下一个悬空指针。Boom,任何访问该地址内存的尝试都是未定义的行为。进监狱,直接进监狱,不通过,不收取200英镑。

我会让您的函数返回一个std::unique_ptr<char[]>,因为它内置了对数组的支持。

std::unique_ptr<char[]> V8StringToChar(Handle<String> str) {
  int len = str->Utf8Length();
  std::unique_ptr<char[]> buf(new char[len + 1]);
  str->WriteUtf8(buf.get(), len + 1);
  return buf;
}
std::unique_ptr<char[]> V8StringToChar(Local<Value> val) {
  return V8StringToChar(val->ToString());
}

要修复运行时故障,您必须将智能指针保留在需要缓冲区的位置,例如

std::unique_ptr<char[]> smartptr = V8StringToChar(whatever);
char* ptr = smartptr.get());
doSomethingWithPtr(ptr);
// now it's OK if `smartptr` goes out of scope