【问题标题】:Segmentation Fault for Expression Tree implementation in CC 中表达式树实现的分段错误
【发布时间】:2021-10-10 18:15:00
【问题描述】:

这里是菜鸟,

我正在尝试实现一个 C 程序来将 POSTFIX 表达式转换为 使用表达式树的有效 PREFIX 表达式。

我创建了 2 个文件,一个 TreeNode.h 文件和一个 main.c 文件

TreeNode.h:

#include <string.h>
#include <stdbool.h>
#include <malloc.h>

typedef char TreeEntry;

typedef struct treenode
{
    char entry;
    struct treenode * left;
    struct treenode * right;
}*TreeNode;


bool isOperator(char c)
{
    if (c == '+' || c == '-' ||
        c == '*' || c == '/' ||
        c == '^'){
            return true;
        }
    return false;
}


TreeNode newNode(TreeEntry v){
    TreeNode temp;
    temp->left = temp->right = 0;
    temp->entry = v;
    return temp;
}

void inOrder(TreeNode n){
    if(n){
        inOrder(n->left);
        printf("%s",n->entry);
        inOrder(n->right);
    }
}

void preOrder(TreeNode n){
    if(n){
        printf("%s",n->entry);
        preOrder(n->left);
        preOrder(n->right);
    }
}

void postOrder(TreeNode n){
    if(n){
        postOrder(n->left);
        postOrder(n->right);
        printf("%s",n->entry);
    }
}


main.c:


#include <stdio.h>
#include "TreeNode.h"

#define MAXSTACK 50

TreeNode stack[MAXSTACK];
int top = -1;

void push(TreeNode n){
    stack[++top] = n;
}

TreeNode pop(){
    TreeNode n = stack[top--];
    return n;
}

TreeNode createExpTree(char postfix[]){
    TreeNode temp,et;
    for (int i = 0; i < strlen(postfix); i++){
        if(!isOperator(postfix[i])){
            temp = newNode(postfix[i]);
            push(temp);
        }else{
            temp = newNode(postfix[i]);
            temp->right = pop();
            temp->left = pop();
            push(temp);
            printf("%c",temp->entry);
        }
    }

    et = pop();
    return et;
}

int main(void){
    char postfix[] = "ab+";
    TreeNode expTree = createExpTree(postfix);
    inOrder(expTree);
    preOrder(expTree);
    postOrder(expTree);
}
    

我不断收到 Segmentation fault ,我无法弄清楚是什么导致了这个错误。 如何解决此错误?请帮忙。

编辑:

我先改了newNode函数

TreeNode * newNode(TreeEntry v){
    TreeNode * temp = (TreeNode *)malloc(sizeof(struct treenode));
    if(temp){
        temp->left = NULL;
        temp->right = NULL;
        temp->entry = v;
    }
    return temp;
}

即使在此更改之后,我仍然收到分段错误错误。

我设法修复了错误,显然错误出现在 TreeNode.h 文件中的 inorder 函数中

我把中序函数改成:

void Inorder(TreeNode *root, void(*Visit)(TreeEntry x))
{
    if (root)
    {
        Inorder(root->left, Visit);
        Visit(root->entry);
        Inorder(root->right, Visit);
    }
}

并更改了 main.c 文件:

void printEntry(TreeEntry te){
    printf("%c",te);
}


int main(void){
    char postfix[] = "ab+";
    TreeNode* expTree = createExpTree(postfix);
    Inorder(expTree,printEntry);
    
}

现在我假设之前的 inorder 函数无法访问传递给它的指针的值,这就是导致错误的原因,

这是什么原因?如果有人能给出解释,我将不胜感激。

【问题讨论】:

  • 您应该尝试使用 gdb 进行调试。或者使用printf() 语句单步执行程序,查看代码中断的位置。
  • 您能描述一下您的尝试吗?编译带有警告启用的代码可以为您提供有用的见解,例如您将createExpTree 中的char 传递给newNode,而不是TreeNode。另外,我建议查看 C 中内存管理的工作原理。声明指针不会分配内存。你应该看看动态内存分配
  • temp-&gt;left = pop(); 我不是每天都做c,但我很惊讶这甚至可以编译,因为pop() 返回一个TreeNode,但TreeNode.left 被声明为struct treenode * left; .
  • @NeonFire 感谢您的回复。我使用 printf 语句来调试代码,我设法修复(见编辑)错误,现在程序按预期工作。中序函数是否无法访问传递给它的指针的值。这是错误的原因吗

标签: c data-structures segmentation-fault binary-tree expression-trees


【解决方案1】:

我认为错误在于 newNode 函数。您将变量temp 声明为TreeNode,这与struct treenode * 相同。所以这意味着你有一个指针,但你没有将它设置为等于任何东西,这意味着它只是指向内存中的某个随机点。因此,当您尝试写入其中一个变量时,您实际上是在写入不属于您的内存,从而导致分段错误。

要解决此问题,您需要为新节点分配一些内存,如下所示:

TreeNode newNode(TreeEntry v){
    TreeNode temp = (TreeNode)malloc(sizeof(struct treenode));
    temp->left = temp->right = 0;
    temp->entry = v;
    return temp;
}

稍后您需要使用free 函数在完成后将此内存归还给操作系统。

【讨论】:

  • 谢谢你的回答,我做了你提到的改变。但之后我仍然遇到段错误。之后我更改了 inode 函数并修复了分段错误,现在程序可以工作了。我将在编辑中所做的更改包含在原始帖子中。为什么之前的inode函数无法访问传递给它的指针的值
  • 我认为这是因为您使用 %s 这意味着它需要一个以空字符结尾的字符串,但您却给了它一个字符。你的编译器没有给你一个警告吗?
猜你喜欢
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 2022-07-21
  • 2018-05-09
  • 2012-06-10
相关资源
最近更新 更多