c - 我一辈子都弄不明白为什么我的 C 程序崩溃了

标签 c binary-tree

我有一个 uni 任务,我必须在其中实现二叉搜索树。它必须获取信息并将其写入磁盘,并将索引存储在树中。但是,每当我调用与树有关的函数时,程序就会崩溃。以下代码片段是我的 bTree.h 文件,以及导致崩溃的代码。

/* binary tree ADT */

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

#define DATA_LENGTH 12
#define POS_LENGTH 8

struct INFO
{
    char data[DATA_LENGTH];
    int filePos;
};

struct NODE
{
    struct INFO data;
    struct NODE *left;
    struct NODE *right;
};


/* 
format for index data file

data identifier     12 bytes
position in file    8 bytes
--end of record--   total 20 bytes

*/

/* 
 Given a binary tree, return true if a node 
 with the target data is found in the tree. Recurs 
 down the tree, chooses the left or right 
 branch by comparing the target to each node. 
*/ 

int lookupPos(struct NODE *node, char target[]) 
{ 
    int length = strlen(target);

    // 1. Base case == empty tree 
    // in that case, the target is not found so return false 
    if (node == NULL) 
    { 
        return -1; 
    }        

    else 
    { 
        // 2. see if found here, in which case return file pos. 
        if (strncmp(target, node->data.data, length) == 0)
        {
            return node->data.filePos;
        }       

        else 
        { 
            // 3. otherwise recur down the correct subtree 
            if (strncmp(target, node->data.data, length) < 0)
        {
            return lookupPos(node->left, target);
        }

            else 
            {
                return lookupPos(node->right, target); 
            }
        }    
    } 
} 


/* 
 Give a binary search tree and a number, inserts a new node 
 with the given number in the correct place in the tree. 
 Returns the new root pointer which the caller should 
 then use (the standard trick to avoid using reference 
 parameters). 
*/ 
struct NODE *insert(struct NODE *node, char info[], int pos) 
{ 
    int length = strlen(info);
    // 1. If the tree is empty, return a new, single node 
    if (node == NULL) 
    { 
        struct INFO stuff; 
        strncpy(stuff.data, info, DATA_LENGTH);
        stuff.filePos = pos;

        node->data = stuff; 
        node->left = NULL; 
        node->right = NULL;

        return(node); 

    }    

    else 
    { 
        // 2. Otherwise, recur down the tree 
        if (strncmp(info, node->data.data, length) <= 0) 
        {
            node->left = insert(node->left, info, pos); 
        }

        else 
        {
            node->right = insert(node->right, info, pos);
        }

        return(node); // return the (unchanged) node pointer 
    } 
} 

struct NODE *loadTree(char filename[]) //cIndex.dat for customers, pIndex.dat for products
{
    struct NODE *node;
    char data[DATA_LENGTH];
    char posStr[POS_LENGTH];

    FILE* file; 
    file = fopen(filename,"rb");

    char c;
    fseek(file, 0, SEEK_SET);

    while((c = fgetc(file)) != EOF) //reads until EOF char
    {
        fseek(file, -1, SEEK_CUR); 


        fread(data, sizeof(char), DATA_LENGTH, file);
        fread(posStr, sizeof(char), POS_LENGTH, file);

        insert(node, data, atoi(posStr));

    }       

    fclose(file);

    return node;
}

int saveTree(struct NODE *node, char filename[], int posInFile)
{
    FILE *file;
    file = fopen(filename, "r+b");

    char c;
    char posStr[POS_LENGTH];

    fseek(file, posInFile, SEEK_SET);

    while((c = fgetc(file)) != EOF)
    {
        fseek(file, -1, SEEK_CUR);

        fwrite(node->data.data, sizeof(char), DATA_LENGTH, file);
        sprintf(posStr, "%d", node->data.filePos);
        fwrite(posStr, sizeof(char), POS_LENGTH, file);

        posInFile = ftell(file);

        saveTree(node->left, filename, posInFile);
        saveTree(node->right, filename, posInFile);
    }

    fclose(file);

    return 1;
}

int getSize(struct NODE *node)
{
    if (node==NULL) 
    { 
        return 0; 
    }

    else 
    { 
        return( getSize(node->left) + 1 + getSize(node->right)); 
    } 
}

现在是有问题的代码片段:

int filePos = getSize(tree);

insert(tree, cust.id, filePos);
saveTree(tree, "cIndex.dat", 0);

谁能帮帮我?

最佳答案

你永远不会分配内存。在您的 insert 函数中:

if (node == NULL) 
{ 
    struct INFO stuff; 
    strncpy(stuff.data, info, DATA_LENGTH);
    stuff.filePos = pos;

    node->data = stuff; 
    node->left = NULL; 
    node->right = NULL;

    return(node); 

}    

“如果 nodeNULL,则开始为其分配内容”。哎呀!

你需要做的是:

node = malloc( sizeof(struct NODE) );

我认为另一个主要问题是:

struct NODE *loadTree(char filename[])
{
    struct NODE *node;
    ...
}

您必须将 node 初始化为 NULL,因为稍后您会在 insert 中使用它的值。

Daniel Fischer 已经指出您在 loadTree 中的字符串可能是一个字节太短(因此您不能可靠地调用 strlen 和相关的字符串函数)。

关于c - 我一辈子都弄不明白为什么我的 C 程序崩溃了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14249834/

相关文章:

c - 在 printf 中使用括号无法正常工作

c - 在预处理器中定义可变参数函数 #define

C 将 BMP 文件大小调整为 N 倍,我做错了什么?

java - 检查树是否是二叉搜索树

algorithm - 为什么在算法中使用子树大小来选择二叉树中的随机节点?

python - 在二叉树中找到最接近给定目标的数字

objective-c - 从自定义结构中找出函数参数?

c++ - 我如何使用 gcc 的内联报告 (-Winline)

c++ - 在奇怪的二叉树中搜索节点

c++ - 以当前节点为根的二进制搜索树插入 C++