2017-10-12 104 views
1

我想連接兩個字符串,所以我可以獲得文件路徑。不過,我在Valgrind的接收錯誤C Strcat valgrind錯誤

條件跳轉或移動依賴於未初始化的值(一個或多個)

我的代碼:

/** 
* @brief Concatenate two strings to get file path 
* @param firstP - First string 
* @param secondP - Second string 
* @return Returns the concatenated string 
*/ 
char *getPathDir(char *firstP, char *secondP) { 
    char *new_str; 
    int stringSize = strlen(firstP)+strlen(secondP)+2; 

    if((new_str = malloc(stringSize)) != NULL){ 
     new_str[0] = '\0'; 
     strcat(new_str,firstP); 
     new_str[strlen(firstP)] = '/'; 
     strcat(new_str,secondP); 
    } else { 
     perror("malloc"); 
     cleanUp(); 
     exit(EXIT_FAILURE); 
    } 
    return new_str; 
} 
+5

'sprintf(new_str,「%s /%s」,firstP,secondP);'而不是。 'new_str [strlen(firstP)] ='/';'覆蓋字符串的最後一個空終止符。所以第二個'strcat'找不到正確字符串的結尾。 – BLUEPIXY

+1

有很多更好的方法來做到這一點... strcat函數。請參閱:https://www.tutorialspoint.com/c_standard_library/c_function_strcat.htm或@BLUEPIXY建議太:) –

+0

@BLUEPIXY我刪除if語句裏面的一切還有使用sprintf(new_str取代它, 「%S /%S」 ,firstP,secondP);它現在完美地工作。謝謝:) – Cows42

回答

6

讓我們來看看這些行:

new_str[0] = '\0'; 
    strcat(new_str,firstP); 
    new_str[strlen(firstP)] = '/'; 
    strcat(new_str,secondP); 

在寫任何東西之前,字符串看起來像這樣:

 +---+---+---+---+---+---+---+---+ 
    | ? | ? | ? | ? | ? | ? | ? | ? | 
    +---+---+---+---+---+---+---+---+ 

後的第一行(new_str[0] = '\0';),你有這樣的:

 +---+---+---+---+---+---+---+---+ 
    | 0 | ? | ? | ? | ? | ? | ? | ? | 
    +---+---+---+---+---+---+---+---+ 

第二行(strcat(new_str,firstP);),它看起來像這樣經過:

 +---+---+---+---+---+---+---+---+ 
    | A | B | C | D | 0 | ? | ? | ? | 
    +---+---+---+---+---+---+---+---+ 

現在,當你執行該行

new_str[strlen(firstP)] = '/'; 

您覆蓋空終止並獲得這樣的:

 +---+---+---+---+---+---+---+---+ 
    | A | B | C | D |/| ? | ? | ? | 
    +---+---+---+---+---+---+---+---+ 

這是一個問題,因爲你的字符串不再是空值終止的,所以當你下次調用strcat程序將啓動讀入內存未初始化狩獵周圍一個空終止符。

如果你想字符串拼接在一起,它可能會更容易,只需使用sprintf,像這樣:

sprintf(new_str, "%s/%s", firstP, secondP); 

此更明確地說:「寫的第一個字符串,然後是分隔符,然後第二個字符串「並將所有空終止符管理卸載到庫中。除了strncat之外,庫通常能很好地處理空終止符。 :-)

還有一個機會,sprintf可能比你所做的更快。由於overhead of rescanning the strings to find the null terminators的原因,連續使用大量strcat s可能效率不高,但我不打賭。然而,它確實有更明確的優勢,可以更準確地傳達您正在嘗試做的事情,而可讀性勝出並不是什麼壞事。

+0

提出問題的絕佳方式。 – Barmar

+0

但你也可以顯示一個簡單的解決方案,增加必要的零,或使用'的strcat(new_str,「/」)' – Barmar

+0

@Barmar這是真的,但可讀性的緣故,我覺得'sprintf'是一個更好的選擇。還有一次又一次的重複掃描字符串(可忽略不計),這是由於在一行中使用了大量的「strcat」而產生的。 – templatetypedef