【问题标题】:Tree traversal - Segmentation fault error树遍历 - 分段错误错误
【发布时间】:2013-08-22 06:20:31
【问题描述】:

代码:

#include<stdio.h>
#include<malloc.h>

typedef struct tree
{
    char data;
    struct tree *left;
    struct tree *right;
}*pos;

pos stack[30];
int top=-1;

pos newnode(char b)
{ 
    pos temp;
    temp=(struct tree*)malloc(sizeof(struct tree));
    temp->data=b;
    temp->left=NULL;
    temp->right=NULL;
    return(temp);
}

void push(pos temp)
{
    stack[++top]=temp;
}

pos pop()
{
    pos p;
    p=stack[top--];
    return(p);
}

void inorder(pos t)
{
    if(t!=NULL)
    {
        inorder(t->left);
        printf("%s",t->data);
        inorder(t->right);
    }
}
void preorder(pos t)
{
    if(t!=NULL)
    {
        printf("%s",t->data);
        preorder(t->left);
        inorder(t->right);
    }
}

void postorder(pos t)
{
    if(t!=NULL)
    { 
        postorder(t->left);
        postorder(t->right);
        printf("%s",t->data);
    }
}

void main()
{
    char *a;
    pos temp,t;
    int j,i;
    puts("Enter the expression :");
    scanf("%s",&a);
    for(i=0;a[i]!='\0';i++)
    {
        if(a[i]=='*' || a[i]=='/' || a[i]=='+' || a[i]=='-')
        {
            temp=newnode(a[i]);
            temp->right=pop();
            temp->left=pop();
            push(temp);
        }
        else
        {
            temp=newnode(a[i]);
            push(temp);
        }
    }
    inorder(temp);
    printf("\n");
    preorder(temp);
    printf("\n");
    postorder(temp);
}

错误:分段错误

此代码用于构造二叉树遍历和后缀到中缀和前缀的转换。我不知道哪里出了问题,但它一直在说同样的错误。 谁能帮我解决这个问题?

【问题讨论】:

  • 您是否尝试过使用调试器?
  • 标签 [dsa] 在这里做什么?

标签: c dsa


【解决方案1】:
    scanf("%s",&a); // is the problem. 

scanf 接受指针,并且您正在传递指针的地址。 你只需要传递指针。

    scanf("%s",a); // since a is already pointer, just use a.

而且你没有分配内存。 您需要分配内存来保存扫描的字符串,就像这样......

    a = (char*)malloc(sizeof(*a) * MAX_SIZE);

【讨论】:

  • 除了指出有问题的构造之外,还应提供一个解决方案:即scanf("%s", a)
  • @alk 当然,兄弟,从现在开始我会牢记这一点,也会更正我的答案。
  • +1 也用于提议使用*a :-)。然而,在 C 中,不应将 malloc/calloc/realloc 的返回值强制转换为不必要也不推荐:stackoverflow.com/a/605858/694576
  • 程序仍然没有运行:/它说错误访问冲突在 0x405888 读取地址 0x31
  • 成功了!问题也在这里---> printf("%s", t->data);我使用格式作为字符串。将其更改为字符,并且完美无缺! :)
【解决方案2】:

你没有正确使用scanf:你给scanf一个指向char的指针的地址,但它没有被初始化:它可能指向一个错误的内存地址,然后你会得到分段错误.

你可以这样做:

# define MAX_BUFF_SIZE (64)

void main()
{
 char a[MAX_BUFF_SIZE];
 pos temp,t;
 int j,i;
 puts("Enter the expression :");
 scanf("%s", a);
 /* ... */
 return 0;
}

或者,如果您更喜欢动态分配:

# define MAX_BUFF_SIZE (64)

void main()
{
 char *a;
 pos temp,t;
 int j,i;
 a = malloc(sizeof(*a) * MAX_BUFF_SIZE);
 if (a == NULL)
     return -1;
 puts("Enter the expression :");
 scanf("%s", a);
 /* ... */
 free(a);
 return 0;
}

顺便提一下,使用scanf 并不安全,如果您想了解更多信息,请阅读this

【讨论】:

  • 完成答案:不仅 scanf 需要一个 char* (即字符串,因为 %s 格式化程序),为结果保留一些内存并指向它也很重要。否则 scanf 将继续并尝试覆盖指针目的地的任何内容,这会导致分段错误。
  • 它不再工作了:/ 它说在 0x405888 读取地址 0x31 时发生错误访问冲突
  • 成功了!问题也在这里---> printf("%s", t->data);我使用格式作为字符串。将其更改为字符,并且完美无缺! :)
【解决方案3】:

这一行

printf("%s", t->data);

尝试将char (t-&gt;data) 打印为0-终止的char 数组(通常称为“字符串”),但不起作用。

要解决此问题,请使用 "%c" 而不是 "%s"

【讨论】:

    【解决方案4】:

    按顺序:

    • C 没有malloc.h 文件。 malloc() 函数和朋友在stdlib.h 中声明。 malloc.h 文件(如果存在)是系统特定的非标准文件,不应使用。
    • int top=-1;?处理索引的奇怪方式。以零为基础的索引有什么问题?
    • 您正在转换malloc() 调用的返回值。在 C 中,通常建议不要这样做。
    • return 不是函数调用,而是语句。
    • 您的push() 函数不进行边界检查。如果您推送超过 30 个项目,您将覆盖不属于您的内存。
    • 您的pop() 函数也没有边界检查。如果您在堆栈中没有任何内容时尝试弹出会发生什么?
    • 您正在使用"%s" 格式说明符来打印char 类型的元素。未定义的行为。 (所有三个遍历函数。)
    • 您的preorder() 函数正在调用inorder()。糟糕。
    • 您将a 声明为char * 类型,但随后将其传递给scanf()。要么将其声明为足够大的数组,要么使用malloc() 来分配您将传递给scanf 的存储空间。 (无论哪种方式,您都应该将 a 而非 &amp;a 传递给 scanf() 函数。)
    • 如果我的输入字符串以*/-+ 开头会怎样?

    【讨论】:

    • 在堆栈中,通常最高值被视为 -1 对吗?这就是为什么我用-1索引它。无论如何谢谢 :) 这教会了我很多!
    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多