2014-01-17 141 views
2

我是C++的新手,學習語言並玩耍。我寫了一段我不明白的行爲。有人可以解釋爲什麼下面的代碼打印出隨機垃圾,而不是列表中第一個字符串的第一個字符(即a)。爲什麼我的函數在返回char時返回垃圾?

#include <iostream> 
#include <vector> 
#include <string> 
#include <cstdlib> 
#include <ctime> 
#include <climits> 
#include <stdio.h> 


char* str2char(std::string str) 
{ 
    char cset[str.size()+1]; // +1 for the null character 
    for(int i = 0; i < str.size(); i++) 
    { 
     cset[i] = str[i]; 
    } 
    cset[str.size()] = '\0'; 
    return cset; 
} 

int main (int argc, char * const argv[]) { 



    std::vector<std::string> ladontakadet; 
    ladontakadet.push_back("aabcbbca"); 
    ladontakadet.push_back("abcdabcd"); 
    ladontakadet.push_back("cbbdcdaa"); 
    ladontakadet.push_back("aadcbdca"); 
    ladontakadet.push_back("cccbaaab"); 
    ladontakadet.push_back("dabccbaa"); 
    ladontakadet.push_back("ccbdcbad"); 
    ladontakadet.push_back("bdcbccad"); 
    ladontakadet.push_back("ddcadccb"); 
    ladontakadet.push_back("baccddaa"); 

    std::string v = ladontakadet.at(0); 
    char *r; 
    r = str2char(v); 
    std::cout << r[0] << std::endl; 
    return 0; 
} 

爲什麼我回來的垃圾,當我期待它輸出a

Thnx任何幫助!

P.S.這段代碼的輸出是隨機的。它並不總是打印相同的字符..:S

+3

今後請不要發佈的代碼截圖,這使得它不可能複製代碼。 –

+0

一個簡單的格式化代碼可以,圖像在這裏是一個矯枉過正。 – legends2k

+2

+1好吧,對不起 – jjepsuomi

回答

1

如果你的目的是要通過一個std的修改一個char *的內容的內容::字符串的函數:

#include <iostream> 
#include <vector> 

void f(char* s) { 
    s[0] = 'H'; 
} 

std::vector<char> to_vector(const std::string& s) { 
    return std::vector<char>(s.c_str(), s.c_str() + s.size() + 1); 
} 

int main(void) 
{ 
    std::string s = "_ello"; 
    std::vector<char> t = to_vector(s); 
    f(t.data()); 
    std::cout << t.data() << std::endl; 
} 
12

這是因爲您返回一個指向局部變量的指針,該局部變量是函數返回時超出範圍的局部變量。

您已經在使用std::string作爲參數,請使用它來代替數組和返回指針。

+0

+1 thnx爲您的幫助...我一直在想我自己(使用字符串代替):(但我的問題是,我正在使用其他人寫的一段代碼,我想要去改變它(因爲它有點長),所以我必須使用char數組x( – jjepsuomi

+3

和可變長度數組首先是不合法的。 – jrok

+3

@jjepsuomi,你總是可以回退並使用'string。 c_str()'來檢索C字符串 – Shoe

2

您的函數正在返回垃圾,因爲您返回的函數返回後超出範圍的局部變量的地址。它大概應該是這樣的:

char* str2char(const std::string &str) 
{ 
    char *const cset = new char[str.size() + 1]; // +1 for the null character 
    strcpy(cset, str.c_str()); 
    return cset; 
} 

您將需要做delete[] r;變量r刪除。理想情況下,儘管您不會使用原始指針,並且您可以使用std::string代替所有內容,也可以將char *代入std::unique_ptr

+0

+1感謝您的幫助@MarkIngram能否解釋更多一點,我沒有完全理解「在你的函數之後超出範圍的局部變量的地址返回」 =),爲什麼它走出去的範圍?:) – jjepsuomi

+1

@jjepsuomi您堆棧(上創建變量'cset' VS堆,這是我的例子做什麼)。在的範圍的端部,在這種情況下,函數(基本上是'{}'括號),意味着該棧被彈出和所有變量被破壞,這意味着你的'cset'變量被破壞。然後你返回你的銷燬變量,這意味着它現在指向垃圾。 –

+0

+1謝謝,清除它:) – jjepsuomi