2017-10-12 11 views
1

두 개의 문자열을 연결하여 파일 경로를 얻을 수 있습니다. 그러나, 나는 Valgrind의에서 오류가 발생하고있어C Strcat valgrind error

조건부 점프 또는 이동은 초기화되지 않은 값 (들)에 따라

내 코드 :

/** 
* @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)] = '/';'는 문자열의 마지막 null 종결자를 덮어 씁니다. 따라서 두 번째'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';)이있다 : 두 번째 줄 (strcat(new_str,firstP);은)는 다음과 같습니다 후

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

:

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

를 이제 때를 줄을 실행하십시오.

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

당신은 널 (NULL) 종료를 덮어 받기 :

 +---+---+---+---+---+---+---+---+ 
    | 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을 많이 사용하는 것이 비효율적 일 수 있지만 그걸 내기는 어렵습니다. 그러나 당신이하려는 일을보다 정확하게 의사 소통한다는 분명한 이점이 있습니다. 가독성은 거의 나쁜 것이 아닙니다.

+0

문제를 제시하는 탁월한 방법. – Barmar

+0

그러나 필요한 널을 추가하는 간단한 해결책을 보여줄 수도 있고'strcat (new_str, "/")'를 사용할 수도 있습니다. – Barmar

+0

@Barmar 사실이긴하지만 읽기 쉽기 때문에'sprintf'가 더 좋은 옵션이라고 생각합니다.또한 많은'strcat'을 연속적으로 사용함으로써 발생하는 문자열 재검색의 비효율적 인 (매우 무시할만한) 비효율적 인 문자열이 있습니다. – templatetypedef