2013-08-20 59 views
0

代碼:樹的遍歷 - 分段錯誤

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

錯誤:段錯誤

該代碼可用於建設二叉樹遍歷後綴,以綴和前綴的轉換。我不知道哪裏會出錯,但它一直說同樣的錯誤。 任何人都可以幫助我嗎?

+0

您是否嘗試過使用調試器呢? – easuter

+0

什麼是標籤[dsa]在這裏做什麼? – alk

回答

2
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); 
+0

除了指出有問題的結構之外,還應提供一個解決方案:即scanf(「%s」,a)'! – alk

+0

@alk哥哥,從現在開始我會記住這一點,並且也會糾正我的答案。 – 2013-08-20 11:07:25

+1

+1也用於提議使用'* a' :-)。但是用C不應該投的malloc'的返回值/釋放calloc/realloc'其沒有必要也不推薦:http://stackoverflow.com/a/605858/694576 – alk

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

或者,如果您prefere動態分配:

# 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如果你想更多信息。

+1

來完成答案:不僅scanf期望char *(即字符串,因爲%s格式化程序),爲結果保留一些內存並指向它也很重要。否則,scanf將繼續並嘗試覆蓋指針目的地處發生的任何事情,這些事件將發生在分段錯誤中。 – Tobias

+0

它不再工作:/它說錯誤訪問衝突在0x405888讀取地址0x31 –

+0

它的工作!問題出現在這裏---> printf(「%s」,t-> data);我用這個格式作爲字符串。改變它的性格,它的工作完美無瑕! :) –

1

此行

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

嘗試打印chart->data)作爲封端0陣列char(通常被稱爲 「串」),它不工作。

要修復此使用"%c"而不是"%s"

+0

謝謝你們! :) –

0

爲了:

  • C沒有一個malloc.h文件。功能和朋友malloc()stdlib.h中聲明。 malloc.h文件(如果存在)是系統特定的非標準文件,不應使用。
  • int top=-1;?奇怪的方式來處理索引。一個指數爲零的指數有什麼問題?
  • 您正在鑄造malloc()調用的返回值。在C中,這通常是不推薦的。
  • return不是函數調用,它是一個聲明。
  • 您的push()函數沒有邊界檢查。如果您推送超過30個項目,則會覆蓋不屬於您的內存。
  • 您的pop()函數也沒有邊界檢查。如果在堆棧上沒有任何東西時嘗試彈出,會發生什麼?
  • 您正在使用"%s"格式說明符來打印類型爲char的元素。未定義的行爲。 (所有這三種遍歷功能。)
  • preorder()功能調用inorder()。哎呀。
  • 您聲明achar *類型,但您將其傳遞給scanf()。將其聲明爲足夠大的數組,或使用malloc()分配您將傳遞給scanf的存儲。 (無論哪種方式,你應該通過a,而不是&a,以scanf()功能。)
  • 如果我的輸入字符串以*/-+開頭會發生什麼?
+0

在堆棧中,通常最高值是-1?這就是爲什麼我用-1索引它。無論如何謝謝:)這教會了我很多! –