2017-02-10 316 views
-1

我想從函數返回一個C字符串。該函數假設用逗號分解3個整數,然後將結果作爲char數組返回,但是我得到的是垃圾值。我假設我沒有正確調用malloc。有人可以就這個問題提出建議嗎?如何使用malloc從函數返回C字符串

using namespace std; 

const char * createCommand(int p1, int p2, int p3){ 
    stringstream sstm; 
    std::string comma = ","; 
    sstm << p1 << comma << p2 << comma << p3; 
    std::string str = sstm.str(); 
    const char *cstr = (const char *)malloc((str.length()+1) * sizeof (char)); 

    cstr = str.c_str(); 
    return cstr;  
} 

int main() { 
    const char *cstr2 = createCommand(1,0,250); //I want to return "1,0,250" 
    printf("char = %s\n",cstr2); 
} 
+0

你在這裏漏了很多。 –

+0

您有*具有*返回c字符串的具體原因嗎?除非你有很好的理由,否則你絕對不應該在C++中編寫這樣的代碼。 – Xirema

+0

在C++中,您應該使用'new'而不是'malloc'來動態分配內存。 – Barmar

回答

2

由於其他兩個答案已經迴應了處理字面問題的曲調,我將改爲建議我認爲是一個非常重要的設計缺陷導致您的問題:返回c字符串。

在您提供的示例代碼中,使用c字符串是毫無意義的。下面的代碼將實現你打算與任何困難或有問題的代碼做什麼:

std::string createCommand(int p1, int p2, int p3){ 
    std::stringstream sstm; 
    std::string comma = ","; 
    sstm << p1 << comma << p2 << comma << p3; 
    return sstm.str(); 
} 

int main() { 
    std::string command = createCommand(1,0,250); //I want to return "1,0,250" 
    std::cout << "char = " << command << "\n"; 
} 

即使你只限於使用printf而不是C++的iostream庫,這個設計還是更好:

std::string createCommand(int p1, int p2, int p3){ 
    std::stringstream sstm; 
    std::string comma = ","; 
    sstm << p1 << comma << p2 << comma << p3; 
    return sstm.str(); 
} 

int main() { 
    std::string command = createCommand(1,0,250); //I want to return "1,0,250" 
    printf("char = %s\n", command.c_str()); 
} 

如果您需要將C字符串傳遞給一些較舊的基於C的庫,則此設計仍然足夠。重點是,沒有理由使用malloc或與底層C字符串表示接口,除非通過字符串本身。

+0

所以你不必處理'command.c_str()'的malloc的原因是因爲它在主要方法? – bakalolo

+0

不,這是因爲'c_str()'只是返回一個指向'std :: string'擁有的內存的指針。 'std :: string'將爲你解決這個問題。 –

+1

@bakalolo你不需要處理malloc的原因是因爲'std :: string'對象管理自己的動態內存。你沒有理由自己去做。 – Xirema

0

在返回指針之前,您需要複製某種形式的字符串strcpy

const char * createCommand(int p1, int p2, int p3){ 
    stringstream sstm; 
    std::string comma = ","; 
    sstm << p1 << comma << p2 << comma << p3; 
    std::string str = sstm.str(); 
    const char *cstr = (const char *)malloc((str.length()+1) * sizeof (char)); 

    strcpy(cstr, str.c_str()); 
    return cstr;  
} 
1

賦值運算符,這對於std::string和其他對象正常工作,不能有指針覆蓋。因此,分配

cstr = str.c_str(); 

泄漏您分配的內存,並用字符串中的數據替換指針。而且,函數返回的指針現在指向退出函數時失效的內存,除了泄漏外,還會創建未定義的行爲。

要解決此問題,請致電std::strcpy(cstr, str.c_str());請不要忘記致電std::free以瞭解有關呼叫的結果。 編輯:你應該從createCommand函數的返回類型中刪除const(WhozCraig,感謝你的評論)。

注:我認爲這只是在使用malloc練習,你知道,使用new[]最好,而且你不會做任何以上的,如果你可以從函數返回std::string

+0

我不會做任何假設。太多「C++程序員」是C程序員,他們認爲C++只是「C類」,或者相同的設計原則適用於這兩種語言。 – Xirema

+0

@Xirema根據OP的資料,它看起來並不像以前有很多C經驗,所以我最好的猜測是這是一個學習練習。 – dasblinkenlight

+0

另外需要注意的一點是:OP的代碼顯示'createCommand'返回'const char *',這在返回'malloc'結果時沒有任何意義,因爲調用者缺少斷裂常量,不能隨意釋放結果指針。這個答案的變化正是OP所需要的,但是另外,調用應該返回'char *',此時由調用者記住'free()'的建議變得可行。 – WhozCraig