2013-09-05 75 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()是否正確? –

相關問題