2014-03-04 144 views
0

嗨,大家好我正在編寫一個程序,讀取大學任務的NMEA語句,並且遇到了分段錯誤問題。有誰能幫我修好嗎?使用strcpy時在構造函數中出現分段錯誤

NmeaSentence::NmeaSentence(std::string sentence) { 
    const char *temp = sentence.c_str(); 
    char *c_sent; 
    strcpy(c_sent, temp); 
    char *pch; 
    for(int i = 0; i < MAX_SENTENCE_PARTS; i++){ 
     pch = strtok(c_sent, ","); 
     this->sentenceParts[i] = pch; 
    } 
    this->sentence = sentence; 
    this->sentenceType = sentenceParts[0]; 
} 

該錯誤似乎發生在strcpy。我究竟做錯了什麼?

+0

可能重複[strcpy with malloc?](http://stackoverflow.com/questions/5354933/strcpy-with-malloc) –

+2

在附註中,爲什麼不在每個地方都使用'std :: string'?是否有特定的需求迫使你通過'(const)char *'來操作字符串? – JBL

+0

您正在使用'strtok'。這是錯誤的。考慮使用Boost.Tokenizer,或從Boost.StringAlgo中分離出來。 –

回答

2

您不會爲c_sent分配內存。這是未定義的行爲。使用char *c_sent = new char[sentence.size() + 1];。我爲空終止符添加了空間。在函數退出前,請不要忘記撥打delete[] c_sent;

(順便說一下,tempsentence的有效期內有效,除非以任何方式進行修改)。

+0

實際上它是有效的,直到句子被修改,所以它是謹慎的,使句子const。 – heinrichj

+0

我不完全確定,我是C++新手 – Will

+0

@heinrichj:這是一個很好的觀點。更好的是,傳遞'const std :: string&sentence'作爲函數參數。 – Bathsheba

0

臨時字符串c_sent未初始化。

char * c_sent 

char * c_sent = strdup(sentence.c_str()); 

不要忘記釋放,退出前。

free(c_sent); 

你不需要這樣的溫度。

+1

我們在這裏使用C++,我建議不要使用'free'等。 – Bathsheba

+0

那麼,如果你使用的是strtok,那麼你可能會使用strdup和free。 –

+0

@Bathsheba你必須在'strdup'中使用'free',儘管使用'strdup'是[可能不是](http:// stackoverflow。com/questions/12984948/why-is-strdup-considered-to-be-evil)一個好主意。 –

0

該成員函數有幾個缺陷。

如果函數的參數,那麼就改變它已經說你不分配內存,你要複製的句子倒不如聲明函數作爲

NmeaSentence::NmeaSentence(const std::string & sentence); 

。指針c_sent未被分配內存的地址初始化。

第二個缺陷是pch始終指向c_sent中的相同地址,因爲您錯誤地使用了函數strtok。您應該使用它通過以下方式

char *pch = strtok(c_sent, ","); 
for(int i = 0; i < MAX_SENTENCE_PARTS && pch; i++){ 
    this->sentenceParts[i] = pch; 
    pch = strtok(NULL, ","); 
} 

而且目前尚不清楚你將如何確定字符串多少部分包含的內容。