我能';我一辈子都不明白为什么我的C程序会崩溃

我能';我一辈子都不明白为什么我的C程序会崩溃,c,binary-tree,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

我有一个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)); 
    } 
}


有人能帮我吗?

你从不分配内存。在
插入功能中:

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); 

}    
“如果
节点
则开始为其分配内容”。哎呀

您需要做的是:

node = malloc( sizeof(struct NODE) );

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

struct NODE *loadTree(char filename[])
{
    struct NODE *node;
    ...
}
您必须将
节点
初始化为
NULL
,因为您稍后会在
insert
中使用它的值


Daniel Fischer已经指出,
loadTree
中的字符串可能太短了一个字节(因此您无法可靠地调用
strlen
及其相关的字符串函数)。

您可以访问调试器吗?这不是有人能给你的最有帮助的建议吗?请提供一个完整的、可编译的程序(main(),等等),除了paddy所说的,
数据标识符12字节
你的
结构节点
中没有空间放置0-终止符。该程序可以编译,没有任何错误。有问题的唯一迹象是程序崩溃。@MattGrima编译它只意味着语法正确。崩溃是一个语义问题。添加了malloc(),但它仍然崩溃。。还有一点不对劲,您在将内容分配给
节点之前添加了它,对吗?=)无论如何,从更大的角度来看,似乎您一次编写了整个程序,而不是测试了部分程序。没有看到你的
main
函数来了解你是如何调用其他函数的,因此很难知道你可能还有什么其他问题。嗯,我刚刚浏览了第二遍。在
loadTree
函数中,声明一个未初始化的
节点
,然后将其传递到
insert
函数中。它的值不一定是空的,所以您马上就会遇到问题,您的函数认为您传递给它的是一棵树,但它只是垃圾。坏事就会发生。在使用它之前,请确保将其初始化为
NULL
,然后再考虑是创建树,还是只创建一组完全隔离的节点。您必须仔细考虑
insert
的返回值以及如何使用它。我已经测试了程序的所有其他部分,唯一有问题的地方是这个二叉树。。我确信int filePos=getSize(tree);是罪魁祸首,但我不明白为什么。不用担心。快乐编码。在将来,千万不要低估printf(或调试器)自己追踪问题的能力…=)
node = malloc( sizeof(struct NODE) );
struct NODE *loadTree(char filename[])
{
    struct NODE *node;
    ...
}