2016-03-03 31 views
0

我有權訪問一個類(不是我寫的),它將const char*作爲構造函數中的參數。如果我有一個字符串,我想傳遞值作爲參數,傳遞它的安全方式是什麼,請記住字符串和類對象可能有不同的作用域?將字符串作爲常量字符傳遞*

我沒有訪問該類的源代碼,所以不要認爲它的做法像將字符串複製到類成員中一樣健全。

舉一個具體的例子,這不起作用:

#include <iostream> 
#include <string> 

class example { 
public: 
    example(const char*); 
    const char* str; 
}; 

example::example(const char* a) : str(a) {} 

int main() { 
    std::string* a=new std::string("a"); 
    example thisDoesntWork(a->c_str()); 
    std::cout << thisDoesntWork.str << std::endl; 
    delete a; 
    std::cout << thisDoesntWork.str << std::endl; //The pointer is now invalid 
    a=new std::string("b"); 
    std::cout << thisDoesntWork.str << std::endl; 
} 

這個工作(只要我可以告訴)更換構造函數,但顯然是很可怕:

example thisDoesWorkButIsAwful((new const std::string(*a))->c_str()); //Memory leak! 

同樣:

char* buffer=new char[a->size()+1]; 
strcpy(buffer,a->c_str()); //with #include <string.h> added up top 
example(buffer); 

但是,這又容易發生內存泄漏。

我目前的主要想法是製作一個圍繞example的包裝類,它將字符串複製到char *緩衝區,並在超出範圍時刪除緩衝區,但看起來有點過分。有更簡單/更好的方法嗎?

+0

更糟糕的是,它可能會承擔指針的所有權,並嘗試稍後「釋放」它。這是特別有趣的,如果你傳遞一個字符串文字,雖然我想這樣的行爲是不是在C API以外的常見:) – melak47

+0

@ melak47我(很漂亮)確定它至少沒有這樣做。儘管在這一點上我很少會感到驚訝。 ;) – Chris

回答

1

基本上,東西需要堅持內存 - 無論你自己做或自動完成。

一種方法來自動執行:

class SuperThatHoldsIt 
{ 
    std::string mString ; 
    SuperThatHoldsIt (std::string const& str) 
    : mString (str) { } 
} ; 
class HoldingExample 
: private SuperThatHoldsIt 
, public example 
{ 
    holdingExample (std::string const& string) 
    : SuperThatHoldsIt (string) 
    , example (mString.c_str()) 
    { } 
} ; 

std::shared_ptr(或boost::shared_ptr)然後創建它,這將抓住它。

std::string myString ("Hello, world!") ; 
std::shared_ptr<HoldingExample> value = std::make_shared<HoldingExample> (myString) ; 

現在這持有的內存和結構。

注:

原因HoldingExample從兩個超類派生是該構造的順序將工作,因爲超類之前局部變量總是初始化。這意味着我們必須在我們自己的成員變量之前構造example,但是我們總是可以初始化一個超類並使用它的成員變量。

如果你通過這個入功能,如

callFunction (*value) ; 

如果他們堅持這種const char*你放開你value後,那麼你仍然有泄漏,你真的可以」不要繞過那個。

相關問題