2014-12-02 112 views
0

我正在構建一個二叉樹BusTree * busTreeHead,然後試圖將它分配給一個具有BusTree * Bushead的結構,並且它正確地分配它,但是當我嘗試訪問二進制搜索樹,特別是名稱,addressOffset和reviewOffset,在包裝程序中的函數外我收到錯誤,如我不明白爲什麼。感謝您的時間。訪問返回的二叉樹內容的問題

下面是我的.c文件

#include "answer10.h" 

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

typedef struct BusList_t{ 
    int id; 
    long int addressOffset; 
    long int reviewOffset; 
    struct BusList_t* next; 
}BusList; 


typedef struct BusTree_t{ 
    char* name; 
    BusList* locations; 
    struct BusTree_t* left; 
    struct BusTree_t* right; 
}BusTree; 

struct YelpDataBST{ 
    const char* business; 
    const char* reviews; 
    BusTree* Bushead; 
}; 

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; 
    int tempID2; 
    int end; 
    long int addressOffset = -1; 
    long int reviewOffset = 0; 
    char line[2000]; 
    char line2[2000]; 
    char* token; 
    char token2[2000]; 
    char name[2000]; 
    char state[2000]; 
    char zip_code[2000]; 
    char address[2000]; 
    int len; 

    BusList* busListHead = NULL; 
    BusTree* busTreeNode = NULL; 
    BusTree* busTreeHead = NULL; 
    fseek(fp_bp,0, SEEK_END); 
    end = ftell(fp_bp); 
    ID = 0; 
    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)){ 
    if(addressOffset == -1){ 
    sscanf(line2, "%d\t%[^\t]", &ID, name); 
    } 
    len = strlen(line); 
    sscanf(line, "%d", &tempID); 
    if(ct == 0){ 
     tempID = 1; 
     ct++; 
    } 
    if((ID != tempID || (ID < 0)) && tempID != 0){ 
     if(tempID == 1) 
     tempID = 0; 
    sscanf(line2, "\t%d\t%[^\t]", &tempID2, token2); 
    if(token2 != NULL){ 
     if(name != NULL) 
     if(strcmp(token2, name) == 0){ 
      fgets(line2, 2000,fp_bp); 
      sscanf(line2, "\t%d\t%[^\t]", &tempID2, token2); 
     } 
     strcpy(name, token2); 
    } 
    reviewOffset = ftell(fp_rp); 
    if(tempID != 0) 
     reviewOffset -= len; 
    ID = tempID;//atoi(token); 
    if(addressOffset == -1){ 
     addressOffset = 0; 
     fgets(line2, 2000,fp_bp); 
    } 
    if(addressOffset != end){ 
     busTreeNode = BusTree_create(name, busListHead, addressOffset, reviewOffset, ID); 
     busTreeHead = BusTree_insert(busTreeHead, busTreeNode); //replace with create node for tree 
    } 
    if(addressOffset != -1) 
     addressOffset = ftell(fp_bp); 
    fgets(line2,2000,fp_bp); 
     } 
     fgets(line,2000,fp_rp); 

} 
    yelp->Bushead = busTreeHead; 
    yelp->business = businesses_path; 
    yelp->reviews = reviews_path; 
    BusTree_print(yelp->Bushead); 
    BusTree_destroy(busTreeHead); 
    fclose(fp_bp); 
    fclose(fp_rp); 
    return yelp; 
} 

BusList* BusNode_create(long int addressOffset, long int reviewOffset, int id){ 
    BusList* loc = malloc(sizeof(BusList)); 
    loc->id = id; 
    loc->addressOffset = addressOffset; 
    loc->reviewOffset = reviewOffset; 
    loc->next = NULL; 
    return loc; 
} 


BusList* BusNode_insert(BusList* head, long int addressOffset, long int reviewOffset, int id){ 
if(head == NULL) 
    return BusNode_create(addressOffset, reviewOffset, id); 
if(BusNode_create(addressOffset, reviewOffset, id) == NULL) 
    return head; 
BusList* newNode = BusNode_create(addressOffset, reviewOffset, id); 
newNode->next = head; 
return newNode; 
} 


void BusList_destroy(BusList* head){ 
    while(head != NULL){ 
    BusList* next = head->next; 
    free(head); 
    head = next; 
    } 
} 

void BusList_print(BusList* head){ 

    while(head != NULL){ 
    printf("addressOffset: %ld reviewOffset: %ld\n",head->addressOffset, head->reviewOffset); 
    head = head->next; 
    } 
} 

//Business Tree of Business Linked Lists 

BusTree* BusTree_create(const char* name, BusList* busListHead, long int addressOffset, long int reviewOffset, int id){ 
    BusTree* node = malloc(sizeof(BusTree)); 
    node->name = strdup(name); 
    node->locations = BusNode_insert(busListHead, addressOffset, reviewOffset, id); 
    node->left = NULL; 
    node->right = NULL; 
    return node; 
} 

BusTree* BusTree_insert(BusTree* root, BusTree* node){ 
    if(root == NULL) 
    return node; 
    if(node == NULL) 
    return root; 

    int cmp = strcmp(node->name, root->name); 

    if(cmp < 0){ 
    root->left = BusTree_insert(root->left, node); 
    } 
    else if(cmp> 0){ 
    root->right = BusTree_insert(root->right, node); 
    } 
    else{ 
    root->locations = BusNode_insert(root->locations, node->locations->addressOffset, node->locations->reviewOffset, node->locations->id); 
    } 
    return root; 
} 

void BusTree_destroy(BusTree* root){ 
    if(root == NULL){ 
    free(root); 
    return; 
    } 
    BusTree_destroy(root->left); 
    BusTree_destroy(root->right); 
    BusList_destroy(root->locations); 
    free(root->name); 
    free(root); 
} 

回答

1

你正在編寫C,不是C++代碼,所以沒有拷貝構造函數。當你這樣做:

yelp->Bushead = busTreeHead; 

你只是做yelp->Bushead指向同一個內存busTreeHead;不執行深度複製。此後不久,當你這樣做:

BusTree_destroy(busTreeHead); 

你釋放內存是yelp->Bushead點,因爲busTreeHead指向同樣的內存。

由於此例程的目的是返回一個YelpDataBST包含您已經建立的BusTree* Bushead,似乎應該簡單地刪除BusTree_destroy(busTreeHead)的呼叫。

順便說一句,我相信你兩次打開你的文件:

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

您應該只打開它們一次。