2014-02-23 9 views
0

나는 여러 문자열을 결합하기 위해 strcat을 사용 해왔다. 내가 다른 문자열로 strcpy로 "SRC"문자열을 복사, 후행 문자 중 '도착 "또는"SRC "문자열에 인쇄되지 않습니다 시도 후문자열 문자가 떨어지나요?

/proc/573/fd/ <- with the backslash 
13   <- length 

: 모든 올바른, 인쇄 것으로 보인다 :

/proc/573/fd <- same string prints without the backslash? 
13   <- length is unchanged? 

strlen으로 전화를 걸면 길이는 변하지 않습니까?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

// This function counts the number of digit places in 'pid' 
int pid_digit_places(int pid) 
{ 
    int n = pid; 
    int places = 0; 
    while (n) 
     n /= 10; 
     places++; 
    return places; 
} 

char *construct_path(int pid, char *dir) 
{ 
    // get count of places in pid 
    int places = pid_digit_places(pid); 
    char *pid_str = calloc(places, sizeof(char)); 

    // create string of pid 
    sprintf(pid_str, "%d", pid); 

    char *proc = "/proc/"; 
    size_t plen = strlen(proc); 
    size_t dlen = strlen(dir) + 1; 
    char *path = calloc(plen + dlen + places, sizeof(char)); 

    strcat(path, proc); 
    strcat(path, pid_str); 
    strcat(path, dir); 

    return path; 
} 

void fd_walk(int pid) 
{ 
    char *fd = "/fd/"; 
    char *fdpath = construct_path(pid, fd); 

    // prints "/proc/573/fd/ - as expected  
    printf("Before: %s\n", fdpath); 

    // shows a length of 13 
    printf("Size Before: %d\n", (int)strlen(fdpath)); 


    char *test = calloc(strlen(fdpath) + 1, sizeof(char)); 
    strcpy(test, fdpath); 

    // prints "/proc/573/fd" no trailing "/" 
    printf("Copied Str: %s\n", test); 

    //shows a length of 13 though 
    printf("Copied Size: %d\n", (int)strlen(test)); 

    // prints "/proc/573/fd" no trailing "/" now  
    printf("After: %s\n", fdpath); 

    // still shows length of 13 
    printf("Size After: %d\n", (int)strlen(fdpath));   
} 

int main(void) 
{ 
    // integer to create path around 
    int pid = 573; 
    fd_walk(pid); 
    return 0; 
} 

내가 -Wallgcc-4.8.2에 컴파일 해요 : 나는 ideone에이 작은 예를 팝했습니다

gcc -o src src.c -Wall 

.

메모리를 할당 할 때 null-terminator에 추가 공간을 추가했는지 확인했습니다.

필자는 포인터를 처음으로 초기화하는 방법을 다시 검토하고 잘못된 점을 보지 않았습니까? printf으로 문자열 인쇄가 예상대로 어떻게되고, 복사 한 후에 printf이 뭔가 다른 것을 인쇄합니까? 정의되지 않은 동작입니까?

+3

제로 터미네이터. 당신은 아마 그들을 잡을 공간을 할당하지 않을 것입니다 ... – Roddy

+0

@Roddy 열쇠는 여기에 "터미네이터"(복수형)입니다. 나는 하나의 터미네이터만을 차지했습니다. 감사합니다 – tijko

+2

주의 :'pid_digit_places'는 1보다 큰 숫자를 반환하지 않습니다. –

답변

3

정확한 코드를 문제없이 실행했습니다. 그럼에도 불구하고, 나는 두 가지 문제를 참조하십시오

// This function counts the number of digit places in 'pid' 
int pid_digit_places(int pid) 
{ 
    int n = pid; 
    int places = 0; 
    while (n) { // <-- The braces were missing here. 
     n /= 10; 
     places++; 
    } 
    return places; 
} 

char *construct_path(int pid, char *dir) 
{ 
    // get count of places in pid 
    int places = pid_digit_places(pid); 

    // You need "places" bytes for the digits, plus one for the zero 
    char *pid_str = calloc(places + 1, sizeof(char)); 

그러나, 일반적으로, 나는 정확히 내가 필요한 메모리를 할당하는 시간을 낭비하지 않을을; 여분의 코드는 크기와 복잡성을 보완합니다.

그냥 가능한 최대 값에 대한 추측을하고, 추측이을 적용 :

// avoid pid_digit_places altogether 
pid_str = malloc(16); 
if (pid > 999999999999L) { 
    // fprintf an error and abort. 

    // Better yet, see whether this is a limit #define'd in the OS, 
    // and place an appropriate compile-time # warning. Chances are 
    // that unless your code's trivial, running it on a system with 
    // such large PIDs (and therefore likely so different an arch!) 
    // would cause some other troube to pop up. 
    // With an # error in place, you save also the pid check! 
} 
+0

한계를 사용하는 것을 생각조차하지 못했습니다. 도와 주셔서 감사합니다! – tijko