2013-09-05 73 views
0

我在我的项目这两个功能:从原始指针到std :: shared_ptr的

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()); 
} 

而且他们的每一次使用到(&*V8StringToChar(whatever))

它完美地构建。

它导致运行时错误。

是否有任何情况下,这可能会失败并请提供一些很好的解决方案?

+3

对于字节数组使用向量。 –

+2

该标准已经提供了一个数组删除器,使用'std :: default_delete '(注意'[]'字符来指定一个数组,因此它使用'delete []') –

+1

可能是因为'&*'给了你一个raw指针,当数组被删除时可以使其失效 - 在你的例子中,这是立即发生的,然后你可以用指针做任何事情。只有当你真的需要一个原始指针时才这样做,并且要非常小心地确保没有任何东西保持指针。 –

回答

5

而不是

(&*V8StringToChar(whatever)) 

你可以这样写:

V8StringToChar(whatever).get() 

但两者都可能是错误的,并保证在某些情况下失败。

这样做会创建一个新的缓冲区,将其作为shared_ptr返回,获取缓冲区的地址,然后shared_ptr超出范围,并且将删除缓冲区,并留下一个悬挂指针。繁荣,任何尝试访问该地址的内存是未定义的行为。去监狱,直接进监狱,不要过去,不要收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 
+1

我可以有他的200英镑吗? –

+0

如果我做的V8StringToChar(不管).get()到处都应该罚款?但它还没有工作。 –

+0

@Jonathan Wakely会V8StringToChar(不管).get()是否正确? –

相关问题