2017-05-15 4 views
-1

아래 tokenize 함수는 sprt가 str에 존재하지 않으면 * size를 0으로 설정합니다. sprt가 "|" 및 STR은 "D AO D"는 청크 [1]은 NULL 포인터를 가리 키도록되어있다하고, N은 0으로 설정되어야한다 : 다음 코드 내의 기능을 테스트 할 때정의되지 않은 동작 : strtok

void 
tokenize(char *str, 
     const char *sprt /*separator*/, 
     char **buffer, 
     int *size /*tokens length*/) 
{ 
    char *chunk[2] = {NULL, NULL}; 

    //store str value into chunk[0] 
    chunk[0] = calloc(strlen(str)+1, sizeof(char)); 
    strcpy(chunk[0], str); 

    if (buffer!=NULL) 
    { 
    int sz = 0; 
    chunk[1] = strtok(str, sprt); 
    while (chunk[1]!=NULL) 
    { 
     buffer[sz] = calloc(strlen(chunk[1])+1, sizeof(char)); 
     strcpy(buffer[sz], chunk[1]); 
     chunk[1] = strtok(NULL, sprt); 
     sz++; 
    } 
    } 
    else 
    { 
    *size=0; 

    //if chunk is not NULL, the iteration begins => size > 0 
    chunk[1] = strtok(str, sprt); 

    while (chunk[1]!=NULL) 
    { 
     (*size)++; 
     chunk[1] = strtok(NULL, sprt); 
    } 

    printf("size=%i\n", *size); 
    } 

    //restore str value from chunk[0] 
    strcpy(str, chunk[0]); 

    if (chunk[0]!=NULL) free(chunk[0]); 
    if (chunk[1]!=NULL) free(chunk[1]); 
} 

그러나 bug: n really needs to be 0! 표시 얻는다 이는 내가 예상대로 strtok 작동하지 못했음을 의미합니다 : 난 정말이 UB 원인을 모르는

int main() 
{ 
    char *test = calloc(7, sizeof(char)); 
    strcpy(test, "D AO D"); 

    int n; 
    tokenize(test, "|", NULL, &n); 
    if (n>0) 
    printf("bug: n really needs to be 0!\n"); 
    else 
    printf("no bug\n"); 
} 

. 내가 뭘 잘못하고있어?

chunk[1] = strtok(str, sprt); 

그런 다음 while 루프 조건이 통과 chunk[1]가 아닌 NULL 포인터이기 때문에,이 문자열에는 "|" 구분이 없기 때문에

+1

'free (chunk [1])'를 호출하지 마십시오; 당신은'malloc' 패밀리로 할당 한 것들만'free'해야합니다. –

+0

이것은 당신이 달려 드는 어떤 문제와도 관련이 없지만'strdup()'가'malloc()'/'strcpy()'조합을 사용합니다. 오류가 발생하기 쉽고 읽기 쉽습니다. –

답변

2

첫 번째 strtok 호출은, 원래 문자열 "D AO D"에 대한 포인터를 반환 :

*size은 첫 번째 반복에서 증가됩니다. 다음 strtok 호출은 '\0' 바이트가 종료됨에 따라 NULL을 반환하며 충족되지 않은 조건으로 인해 루프가 종료됩니다. 따라서 *size1과 같아지고 이는 예상되는 동작입니다.

+0

strtok이 잘못된 구분 기호 인 경우 원래 문자열을 반환한다고 발표하지 않았습니다. 감사. – Kais

+1

@Kais : 문자열에 구분 기호가 없으면 문자열이 유일한 토큰입니다. –

관련 문제