2014-11-23 4 views
0

이전에 strdup()을 사용했습니다. 여기에서 사용하는 것과 같습니다. token2를 strdup에 전달합니다.이 strdup는 유효한 포인터가있는 char * 유형이며, "name = strdup (token2);"줄을 실행하려고 할 때 사용됩니다. 내 프로그램 segfaults 그리고 나는 확실히 확신 할 수 없다. 누구든지 나를 도울 수 있다면 크게 감사하겠습니다. 나는 또한 내 코드가 적절한 타입을 반환하지 않는다는 것을 알고있다. 나는 아직도 그것을 작성하는 중이다.strdup를 사용하려고 할 때 C - segfault

struct YelpDataBST* create_business_bst(const char* businesses_path, const char* reviews_path){ 

    if(fopen(businesses_path,"r") == NULL || fopen(reviews_path,"r") == NULL) 
    return NULL; 
    FILE* fp_bp = fopen(businesses_path, "r"); 
    FILE* fp_rp = fopen(reviews_path, "r"); 

    struct YelpDataBST* yelp = malloc(sizeof(struct YelpDataBST*)); 

    int ID = -1; 
    int tempID; 
    long int addressOffset; 
    long int reviewOffset; 
    char line[2000]; 
    char line2[2000]; 
    char temp[2000]; 
    char temp2[2000]; 
    char* token; 
    char* token2; 
    char* name; 
    int len; 

    BusList* busNode = NULL; 
    BusList* busList = NULL; 
    BusTree* busTreeNode = NULL; 
    BusTree* busTree = NULL; 

    ID = -1; 
    tempID = 0; 
    fgets(line,2000,fp_rp); 
    fgets(line2,2000,fp_bp); 
    fseek(fp_rp,0, SEEK_SET); 
    fseek(fp_bp,0,SEEK_SET); 
    int ct = 0; 
    while(!feof(fp_rp)){ 

    len = strlen(line); 
    token = strtok(line, "\t"); 
    //printf("line: %s\n", line); 
    token2 = strtok(line2, "\t"); 
    tempID = atoi((char*)strdup(token)); 
    if(ct == 0){ 
     tempID = 1; 
     ct++; 
    } 

    if((ID != tempID || (ID < 0)) && tempID != 0){ 
    if(tempID == 1) 
     tempID = 0; 
    token2 = strtok(NULL, "\t"); 
    //name = strdup(token2); 
    reviewOffset = ftell(fp_rp); 
    if(tempID != 0) 
     reviewOffset -= len; 
    addressOffset = ftell(fp_bp); 
    ID = atoi((char*)strdup(token)); 
    busList = BusNode_insert(busList, addressOffset, reviewOffset); //replace with create node for tree 
    token2 = strtok(NULL, "\t"); 
    token2 = strtok(NULL, "\t"); 
    token2 = strtok(NULL, "\t"); 
    token2 = strtok(NULL, "\t"); 
    token2 = strtok(NULL, "\t"); 
    token2 = strtok(NULL, "\n"); 
    fgets(line2,2000,fp_bp); 
    } 
    token = strtok(NULL, "\t"); 
    token = strtok(NULL, "\t"); 
    token = strtok(NULL, "\t"); 
    token = strtok(NULL, "\t"); 
    token = strtok(NULL, "\n"); 
    fgets(line,2000,fp_rp); 

    } 

    //BusList_print(busList); 

} 
+1

이 줄은 잘못된 수의 바이트를 할당합니다 :'struct YelpDataBST * yelp = malloc (sizeof (YelpDataBST *) 구조체), ' –

+1

'tempID = atoi ((char *) strdup (token)); (strdup() 포인터가 사용되었지만 할당되지 않았습니다) – wildplasser

+0

예, wildplasser가 말했듯이; 당신은 단지 'tempID = atoi (토큰);'만 필요합니다. (char *를 char *로 타입 변환 할 필요가 없습니다 ... –

답변

0

strdup(token) segfaulting은 대부분 token 존재의 NULL에 의해 설명된다. (당신은 어쨌든 여기에 strdup 필요가 없습니다). 코드의 부분 변경 :

if (token == NULL) 
{ 
    fprintf(stderr, "Invalid data in file.\n"); 
    exit(EXIT_FAILURE); // or some other error handling 
} 

tempID = atoi(token); 

은 그러나 주변의 코드에 더 큰 문제는 한 번에 두 번 strtok을 사용하려고한다는 것입니다. 내부 상태를 유지하며 한 번에 하나만 strtok을 "진행 중"으로 설정할 수 있습니다. 두 번째 것은 첫 번째 것을 취소합니다. 해당 코드 섹션을 다시 디자인해야합니다. 또한


, while(!feof(fp_rp)) is wrong하고 yelp mallocs 바이트의 잘못된 번호 (코드를 게시 실제로는 아직 오류가 발생하지 않을 수 있도록, 해당 스토리지에 아무것도 저장하지 마십시오 있지만).

+0

그건 이상한 일입니다. 프로그램 segfaults가 주석 처리 된 섹션에서 "name = strdup (token2) "그리고 gdb를 통해이 프로그램을 실행하고 token2가 null 인 경우 segfaults인지 확인합니다.하지만 문자 포인터가 포함되어 있지 않습니다. 이것이 이유를 이해하지 못하는 이유입니다 segfault –

+0

@ user3466964를 주면 누군가가 코드를 디버그하도록 [MCVE] (http://stackoverflow.com/help/MCVE)를 게시해야합니다. 너무 많은 미지수가 있습니다 (예 : 힙 손상이 –

+0

왜 내가 segfaulting하고 도움을 주셔서 감사합니다 문제가 해결 알아 냈어! 당신은 얼마나 많은 옐프 mallocs 바이트의 잘못된 숫자를 설명 할 수 있을까요? 나는 당신이 무슨 뜻인지에 관해서는 조금 혼란 스러워요. sizeof (struct YelpDataBST *)를 mallocing 할 때. 그냥 구조체의 해당 유형에 필요한 바이트 수를 그냥 malloc 아닌가요? –