我的项目中有这两个函数:
char* V8StringToChar(v8::Handle<v8::String> str);
char* V8StringToChar(v8::Local<v8::Value> val);
Run Code Online (Sandbox Code Playgroud)
我将它们转换为:
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);
Run Code Online (Sandbox Code Playgroud)
与身体一样
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());
}
Run Code Online (Sandbox Code Playgroud)
并且每次使用它们(&*V8StringToChar(whatever)).
它构建完美.
它导致运行时错误.
有没有可能失败的情况请提供一些好的解决方案?
代替
(&*V8StringToChar(whatever))
Run Code Online (Sandbox Code Playgroud)
你可以写:
V8StringToChar(whatever).get()
Run Code Online (Sandbox Code Playgroud)
但两者都可能是错误的,并且在某些情况下保证会失败.
这样做会创建一个新的缓冲区,将其作为a返回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());
}
Run Code Online (Sandbox Code Playgroud)
要修复运行时故障,只要需要缓冲区,就必须保持智能指针
std::unique_ptr<char[]> smartptr = V8StringToChar(whatever);
char* ptr = smartptr.get());
doSomethingWithPtr(ptr);
// now it's OK if `smartptr` goes out of scope
Run Code Online (Sandbox Code Playgroud)