在创建bst时泄露内存,需要解析帮助

时间:2016-11-15 23:48:39

标签: c parsing memory-leaks

Node *addToTree(Node *head, Node *newNode) {
    if (head == NULL) {
        head = newNode;
    } else {
        if (newNode->price < head->price) {
            head->left = addToTree(head->left, newNode);
        } else
        if (newNode->price > head->price) {
            head->right = addToTree(head->right, newNode);
        } else
        if (newNode->price == head->price) {
            free(newNode);
        }
    }
    return head;
}

Node *getCars(char *name) {
    FILE *fp;
    if ((fp = fopen(name, "r")) == NULL) {
        return NULL;
    } else {
        Node *head = NULL;
        Node *tmp;
        char delim[2] = "|";
        char car[MAXLINELENGTH] = {0};
        char *token = NULL;
        int ch;
        while (!feof(fp)) {
            tmp = malloc(sizeof(Node));
            tmp->left = tmp->right = NULL;
            fgets(car, MAXLINELENGTH, fp);
            token = strtok(car, delim);
            while (token != NULL) {
                if (strcmp(token, "model") == 0) {
                    token = strtok(NULL, delim);
                    strcpy(tmp->model, token);
                } else
                if (strcmp(token, "make") == 0) {
                    token = strtok(NULL, delim);    
                    strcpy(tmp->make, token);
                } else
                if (strcmp(token, "price") == 0) {
                    token = strtok(NULL, delim);                
                    tmp->price = atoi(token);
                } else
                if (strcmp(token, "year") == 0) {
                    token = strtok(NULL, delim);                
                    tmp->year = atoi(token);
                } else
                if (strcmp(token, "color") == 0) {
                    token = strtok(NULL, delim);    
                    strcpy(tmp->color, token);
                } else
                if (strcmp(token, "type") == 0) {
                    token = strtok(NULL, delim);
                    if (token == NULL) {
                        break;
                    }   
                    strcpy(tmp->type, token);
                } else
                if (strcmp(token, "mileage") == 0) {
                    token = strtok(NULL, delim);    
                    tmp->mileage = atoi(token);
                }
                token = strtok(NULL, delim);
            }
            if (check("makes.txt", tmp->make) != 1) {
                continue;
            } else
            if (check("colors.txt", tmp->color) != 1) {
                continue;
            } else
            if (check("types.txt", tmp->type) != 1) {
                continue;
            } else {
                head = addToTree(head, tmp);
            }
        }
        free(tmp);
        fclose(fp);
        return head;
    }
}

因此,对于家庭作业,我应该通过输入文件解析大约10000个汽车信息,包括品牌,型号,颜色,类型,价格,里程和年份,并根据其价格将其输入BST当我运行代码时,它表示我在使用tmp指针的malloc行丢失了274个字节。我只是想知道这个解决方案是什么,而且我真的可以解析任何建议/帮助,因为我的getCars功能很难看,而且运行大约需要15秒,非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

您的代码中存在多个问题:

  • while (!feof(fp))总是错的。请阅读:Why is “while ( !feof (file) )” always wrong?

  • 您应该检查所有属性的缺失值。

  • 如果未能匹配品牌,颜色或类型,则不会释放节点。

  • 解析循环后你不应该释放tmp:它可能已插入BST,如果文件为空,它甚至可能未被初始化。

  • 令人惊讶的是,您没有将汽车插入BST,而另一辆汽车价格相同......您应该更准确地检查重复汽车。

以下是改进版本:

Node *addToTree(Node *head, Node *newNode) {
    if (head == NULL) {
        head = newNode;
    } else {
        if (newNode->price < head->price) {
            head->left = addToTree(head->left, newNode);
        } else
        if (newNode->price > head->price) {
            head->right = addToTree(head->right, newNode);
        } else
        if (newNode->price == head->price) {
            free(newNode);
        }
    }
    return head;
}

Node *getCars(const char *name) {
    FILE *fp;
    if ((fp = fopen(name, "r")) == NULL) {
        return NULL;
    } else {
        Node *head = NULL;
        char delim[] = "|";
        char car[MAXLINELENGTH];

        while (fgets(car, sizeof car, fp)) {
            Node *tmp = malloc(sizeof(Node));
            /* initialize all members */
            tmp->left = tmp->right = NULL;
            tmp->model[0] = tmp->make[0] = tmp->color[0] = tmp->type[0] = '\0';
            tmp->price = tmp->year = tmp->mileage = 0; 
            char *token = token = strtok(car, delim);
            while (token != NULL) {
                if (strcmp(token, "model") == 0) {
                    token = strtok(NULL, delim);
                    if (token == NULL) break;
                    strcpy(tmp->model, token);
                } else
                if (strcmp(token, "make") == 0) {
                    token = strtok(NULL, delim);    
                    if (token == NULL) break;
                    strcpy(tmp->make, token);
                } else
                if (strcmp(token, "price") == 0) {
                    token = strtok(NULL, delim);                
                    if (token == NULL) break;
                    tmp->price = atoi(token);
                } else
                if (strcmp(token, "year") == 0) {
                    token = strtok(NULL, delim);                
                    if (token == NULL) break;
                    tmp->year = atoi(token);
                } else
                if (strcmp(token, "color") == 0) {
                    token = strtok(NULL, delim);    
                    if (token == NULL) break;
                    strcpy(tmp->color, token);
                } else
                if (strcmp(token, "type") == 0) {
                    token = strtok(NULL, delim);
                    if (token == NULL) break;
                    strcpy(tmp->type, token);
                } else
                if (strcmp(token, "mileage") == 0) {
                    token = strtok(NULL, delim);    
                    if (token == NULL) break;
                    tmp->mileage = atoi(token);
                }
                token = strtok(NULL, delim);
            }
            if (check("makes.txt", tmp->make) != 1
            ||  check("colors.txt", tmp->color) != 1
            ||  check("types.txt", tmp->type) != 1) {
                /* unrecognized make, type or color: discard entry */
                free(tmp);
            } else {
                head = addToTree(head, tmp);
            }
        }
        fclose(fp);
        return head;
    }
}