>我正在构建一个二叉树 BusTree* busTreeHead,然后尝试将其分配给包含 BusTree* Bushead 的结构,并且它正确地分配了它,但是当我尝试访问二叉搜索树的内容时,特别是名称、地址偏移量和 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, "%dt%[^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%dt%[^t]", &tempID2, token2);
if(token2 != NULL){
if(name != NULL)
if(strcmp(token2, name) == 0){
fgets(line2, 2000,fp_bp);
sscanf(line2, "t%dt%[^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: %ldn",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);
}
您正在编写 C,而不是 c++,因此没有复制构造函数。 当您执行以下操作时:
yelp->Bushead = busTreeHead;
你只是yelp->Bushead
指向与busTreeHead
相同的内存;不执行深拷贝。 此后不久,当您执行以下操作时:
BusTree_destroy(busTreeHead);
您正在释放yelp->Bushead
指向的内存,因为busTreeHead
指向相同的内存。
由于此例程的目的是返回包含已构建BusTree* Bushead
的YelpDataBST
,因此似乎应该简单地删除对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");
您只应打开它们一次。