2012-02-23 134 views
1

我正在嘗試編寫一個函數將std :: string轉換爲char *。 我寫的第一個是這樣的:將字符串轉換爲char *

char* $ (string str) 
{ 
    char* cstr; 
    const unsigned int length=str.size(); 
    cstr=new char[1000]; 
    for(int i=0;i<length;i++) 
     cstr[i]=str[i]; 
    cstr[length]=0; 
    return cstr; 
} 

但問題是內存泄漏:讓我們假設我這樣做:

char* cstr; 
string str1("hello"),str2("hello2"); 
cstr=$(str1); 
cstr=$(str2); 

有這case.The內存泄漏第一分配的字符串不可訪問,但它的引用丟失。 所以我使用靜態由相同:

char* $ (string str) 
{ 
    static char cstr[1000]; 
    const unsigned int length=str.size(); 
    for(int i=0;i<length;i++) 
     cstr[i]=str[i]; 
    cstr[length]=0; 
    return cstr; 
} 

但現在的問題是,靜態字符字段是可訪問:

char* cstr; 
string str("hello"); 
cstr=$(str); 
$(str)[5]='!'; 

這是不可能性,第6個字符被修改,因此也是C由cstr指定的字符串被修改。

中使用const:

const char* $ (string str) 
{ 
    static char cstr[1000]; 
    const unsigned int length=str.size(); 
    for(int i=0;i<length;i++) 
     cstr[i]=str[i]; 
    cstr[length]=0; 
    return cstr; 
} 

的問題是一個字符指針是不是一個const char指針兼容,所以我不能做到這一點:

string str("hello"); 
char* cstr; 
cstr=$(str); 

但我只能用一個常量字符指針。 我會做的是有一個函數,它的返回值只能作爲右操作數,而不能作爲賦值的左操作數。如何完成?

我試着這樣做:

char* toCharArray(string& str) 
{ 
    std::unique_ptr<char>p(new char[1000]); 
    char* temp=p.get(); 
    for(unsigned int i=0;i<str.size();i++) 
    { 
     *temp=str[i]; 
     temp++; 
    } 
    return p.get(); 
} 

但問題仍然存在,我不認爲這與其他解決方案之間的差別我張貼使用static.Since一個這樣的代碼:

char* cstr; 
string str("hello"); 
cstr=toCharArray(str); 
toCharArray(str)[0]='o'; 
cout << cstr; 

修改字符串(打印「oello」)。 問題仍未解決。

+8

你已經寫了一個名爲'$'的函數? – 2012-02-23 12:48:03

+4

「在這種情況下存在內存泄漏。第一個分配的字符串不可訪問,但它的引用已丟失。」您的功能無法保護客戶端代碼不被視爲白癡。如果你想防止泄漏,你使用'std :: string',如果你使用'char *',你知道如果你不小心你可能會泄漏。唯一的另一種解決方案是將一個智能指針返回給char *(特別是一個數組,否則它將調用delete而不是delete [])。 – 2012-02-23 12:53:52

+0

你想用'cstr'做什麼?也許你的問題可以用更聰明的方式解決。例如使用const_cast '從'str.c_str()'中移除'const'? – jofel 2012-02-23 13:04:59

回答

-3

str.c_str()怎麼樣?或者如果你想要一份副本,則需要strdup(str.c_str())

+0

我可以使用這個,但我正在嘗試執行此功能的練習。 – 2012-02-23 12:49:12

+4

我無法用足夠快的速度降低它的速度。 'strdup(str.c_str())'中的錯誤數量是壓倒性的。 – 2013-08-01 15:03:11

+0

@ R.MartinhoFernandes謹慎闡述?最好不止於「我個人不喜歡在C++中使用C函數」。 – 2013-08-01 15:21:35

1

您需要創建一個新的char *並將std::string的內容複製到其上。可以使用strcpy

0

我不明白你爲什麼要由內存泄漏感到驚訝。如果你正在製作一些東西,你必須把它放在某個地方。

您可以將所有副本放在同一個位置(運行有溢出風險,並且承擔在客戶端上正確複製的責任,或者他們冒着意外損壞的風險),或者執行分配(他們仍然需要解放,但至少他們不需要複製),或者讓他們將緩衝區和大小傳遞給你的函數。

嚴重的是,$作爲函數名嗎?

+0

一個名稱函數應該是有意義的,我認爲$給出了當你在彙編中使用$來獲得寄存器值時你正在做什麼的想法。 我會改變名字,因爲就像西摩在上面的文章中所說的那樣,它不是可移植的。 – 2012-02-23 13:50:13

+0

你讀過完整的問題嗎?我使用了一個char的靜態數組。 – 2012-02-23 15:15:05

+0

是的,我做到了。我使用malloc/new的第一個示例。一個char類型的靜態數組有其他問題(例如,如果字符串長度超過1k,該怎麼辦?如果客戶端不重複該字符串,並在其他人使用該函數後引用它) – 2012-02-23 17:05:06

2

您可以通過將分配的數組返回爲std::unique_ptr<char[]>std::vector<char>來防止內存泄漏;如果它們被重新分配或超出範圍,它們都會釋放內存。

您可以分別得到char*指向內容的指針,分別爲ptr.get()&vec[0]

順便說一句,由於長度是已知的,陣列長度應該是length+1,而不是1000。固定大小的緩衝區是等待發生的溢出。另外,$不是函數的便攜式名稱。

+0

只是一個問題:與長度聲明爲const,將長度+1給編譯器錯誤可變長度數組還是不行? – supertopi 2012-02-23 13:28:56

+0

@supertopi:沒關係 - 聲明'const'不會阻止你使用它的值,這就是你正在做的所有事情,如果你在'new char [length + 1]'或者std :: vector中使用它'' (長度+ 1)'。 – 2012-02-23 13:35:48