소스코드에는 문제가 없는데 실행시켜서 값을 입력하면 중단이 됩니다....

rainbow2316의 이미지

#include <stdio.h>
#include <stdlib.h>
 
 
typedef struct TreeNode
{
 char data;
 struct TreeNode *left, *right;
}TreeNode;
 
#define MAX_STACK_SIZE 100
 
typedef TreeNode* element;
 
typedef struct
{
 element stack[MAX_STACK_SIZE];
 int top;
}StackType;
 
element push(StackType *s, TreeNode *p)
{
 s->top++;
 
 return s->stack[s->top] = p;
 
}
 
element pop(StackType *s)
{
 s->top--;
 return s->stack[s->top];
}
 
TreeNode * makeET(char *expr, StackType *s)
{
 char ch;
 TreeNode *p;
 
 while(*expr != '\0')
 {
  ch = *expr;
 
  switch(ch)
  {
   case '+':
   case '-':
   case '*':
   case '/':
    p = (TreeNode*)malloc(sizeof(TreeNode));
    p->data = ch;
    p->right = pop(s);
    p->left = pop(s);
    push(s, p);
    break;
 
   default:
    p = (TreeNode*)malloc(sizeof(TreeNode));
    p->data = ch;
    p->right = NULL;
    p->left = NULL;
    push(s,p);
    break;
  }
 }
 return p;
}
 
 
 
void inorder(TreeNode *p)
{
 if(p != NULL)
 {
  inorder(p->left);
  printf("%d", p->data);
  inorder(p->right);
 }
}
 
void preorder(TreeNode *p)
{
 if( p != NULL)
 {
  printf("%d", p->data);
  preorder(p->left);
  preorder(p->right);
 }
}
 
void postorder(TreeNode *p)
{
 if(p != NULL)
 {
  postorder(p->left);
  postorder(p->right);
  printf("%d", p->data);
 }
}
 
 
int main(void)
{
 StackType s;
 TreeNode* p;
 char expr[10];
 s.top = -1;
 
 
 printf("input expr :");
 scanf("%s", expr);
 
 
 p = makeET(expr, &s);
 
 inorder(p);
 preorder(p);
 postorder(p);
 
}

이곳저곳 수정해서 만든 소스입니다.
근데 실행시켜서 값을 입력하면 실행이 되질 않고 중단이 되버립니다.
왜 그런지 혹시 알 수 있을까요 ....
왜 에러가 뜨는지 알수가 없어서..ㅠ

익명 사용자의 이미지

일단 push와 pop 함수의 동작을 잘 확인해 보기 바랍니다.

mirheekl의 이미지

실행해보니 push에서 잘못된 주소에 쓰기를 시도하는군요. 스택 레벨 관리에 문제가 있는걸로 보이고요. 예외가 발생할 때 보니까 스택 인덱스 숫자가 엄청나게 커져있네요.
중단이 되는 건 당연히 이런 예외상황이 발생했기 때문입니다. 어디선가 정상적으로 종료된게 아니고요.
디버거 사용이 여의치 않으면 push랑 pop등에 디버깅 코드를 넣어서 값을 찍어보게 하시면 됩니다. 아니면 키 입력을 한번씩 받게 해서 스텝으로 동작하게 해봐도 좋고요.

아참 그리고 소스코드에 문제가 없다기보단 그냥 빌드 에러가 없는 것이겠지요? 소스 코드에 문제가 없다고 확신할 수 있는 경우는 정말 드뭅니다. 런타임 에러란건 언제 어떻게 발생할지 모르기에..

그래서 개인적으로 자료구조 공부에는 자바나 C#등등 가베지 컬렉션을 제공하는 언어를 이용하는게 좋다 생각합니다. 왜냐하면 주소관리에 익숙치 않은 상태에서 해당 작업을 C에서 하게 되면 이부분을 디버깅하느라고 원래의 목적인 자료구조 공부는 뒷전이 되고 포인터와 주소 공부를 하게 되거든요. (반대로 이부분을 제대로 다룰 줄 아는 상태에서라면 언어별로 별 차이는 없게 되겠죠.)

물론 지금 발생한 에러는 엄밀히 말하면 포인터때문에 생긴 에러는 아니지만, 다른 언어를 사용하셨으면 훨씬 수월하게 끝내셨을거란 생각엔 변함이 없습니다.

--

seokhong.kim의 이미지

// 인덱스 증가 후, 값 저장
element push(StackType *s, TreeNode *p)
{
s->top++;

return s->stack[s->top] = p;

}

// 인덱스 감소 후, 값 출력
element pop(StackType *s)
{
s->top--;
return s->stack[s->top];
}

pop 함수에서 값 출력 후, index를 감소시켜야 되지 않나요?

익명 사용자의 이미지

makeET에서 ch값은 변화가 없네요. 무한루프를 돌겠네요. 그리고 입력이 1+2 이런 식으로 되는 거 맞나요? 그러면 그 때 makeET에서 어떤 일이 발생하는지 한 번 따라가보세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.