2013-07-31 11 views
0

포인터를 사용하여 스택을 구현했습니다. 그것은 컴파일 및 작동하지만 스택이 비어있을 때 언더 플로우하지 않습니다. 그것은 나에게 쓰레기 값을 준다. 나는 문제가 create_stack 함수에있는 것이라고 생각한다. 이상한 스택에서 얼마나 많은 데이터가 유출 되더라도 segfaults를 얻지는 못합니다.C에서 포인터로 스택 스택 언더 플로를 제외하고 작동

아무도 도와 줄 수 있습니까?

여기에 포인터를 통한 스택 구현이 나와 있습니다.

#include<assert.h> 
#include<stdio.h> 
#include<stdlib.h> 

enum action {PUSH = 1, POP, TOP, QUIT}; 

typedef struct node 
{ 
    int data; 
    struct node *lower; 

}stack_node; 

void clear_screen(void) 
{ 
    system("cls"); 
} 

static enum action get_user_action(void) 
{ 
    int choice = 0; 
    do 
    { 
     clear_screen(); 
     printf("%d Push data\n" 
       "%d Pop Data\n" 
       "%d See the top of the stack\n" 
       "%d Exit\n\n" 
       "Enter your choice -> ", PUSH, POP, TOP, QUIT); 
     scanf("%d", &choice); 
    } while (choice != PUSH && choice != POP && choice != TOP && choice != QUIT); 
    return (enum action) choice; 
} 

void create_stack(stack_node **top, int *status) 
{ 
    *top = malloc(sizeof(stack_node)); 

    *status = PUSH - 1; 
    if (*top == NULL){ 
     *status = PUSH; 
    } 
} 

void push(stack_node **top_stack, int *status, int data) 
{ 
    *status = PUSH - 1; 
    stack_node *node = malloc(sizeof(node)); 
    if (node == NULL) 
    { 
     *status = PUSH; 
     return; 
    } 

    node -> data = data; 
    if (*top_stack == NULL){ 
     node -> lower = NULL; 
    } 
    else{ 
     node -> lower = *top_stack; 
    } 
    *top_stack = node; 
} 

int pop(stack_node **top_stack, int *status) 
{ 
    *status = PUSH - 1; 
    if (*top_stack == NULL){ 
     *status = POP; 
     return -1; 
    } 

    stack_node *node = *top_stack; 
    int data = node -> data; 
    *top_stack = node -> lower; 
    free(node); 

    return data; 
} 

int see_top(stack_node **top_stack, int *status) 
{ 
    *status = PUSH - 1; 
    if (*top_stack == NULL){ 
     *status = POP; 
     return -1; 
    } 

    return (*top_stack) -> data; 
} 

int main(void) 
{ 
    enum action choice; 
    int status; 

    stack_node *top = NULL; 
    create_stack(&top, &status); 

    if (status == PUSH) 
    { 
     printf("Not enough memory\n"); 
     return 1; 
    } 

    while ((choice = get_user_action()) != QUIT) 
    { 
     clear_screen(); 
     int data; 
     switch (choice) 
     { 
     case PUSH: 
      printf("Enter data to be pushed -> "); 
      scanf("%d", &data); 
      push(&top, &status, data); 
      if (status == PUSH){ 
       printf("Not enough memory\n"); 
      } 
      break; 
     case POP: 
      data = pop(&top, &status); 
      if (status == POP){ 
       printf("Stack underflow\n"); 
      } 
      else{ 
       printf("The data is %d\n", data); 
      } 
      break; 
     case TOP: 
      data = see_top(&top, &status); 
      switch (status) 
      { 
      case POP: 
       printf("Nothing in the stack\n"); 
       break; 
      default: 
       printf("The data at top is %d\n", data); 
      } 
      break; 
     default: 
      assert(!"You should not have reached this."); 
     } 
     getchar(); 
     getchar(); 
    } 
} 
+1

왜 함수가 메모리를 할당합니까? –

+0

@GrijeshChauhan 재사용 가능한 스택 구현을 만들고 싶습니다. 함수에 할당 된 메모리가 누출되지 않도록주의하기 위해'struct to pointer to pointer '포인터를 사용하고 있습니다. 할당 된 메모리는 스택에 배치됩니다. 그러나 내가 말했듯이 나는이 기능에 실수가 있다고 진지하게 생각한다. 그것은 얼굴에서 나를 빤히 쳐다보고있는 것 같지만 나는 단지 그것이 무엇인지 놓을 수 없었다. –

+1

할당은 가비지 값을 반환하고 후속 팝 작업 후에는 정의되지 않은 동작의 원인 일 수 있습니다. –

답변

2

스택을 만들 때 노드에 공간을 할당하고 아무 것도 채우지 않습니다. 그래서 create_stack()을 호출 한 후에 이미 스택에 빈 노드가 있습니다. 그냥하고 싶지 않아요.

void create_stack(stack_node **top, int *status) 
{ 
    *top = NULL; 
    *status = PUSH -1; 
} 

잘 작동합니다. 어쨌든 함수 중에 top_stack == NULL을 확인하는 push() 호출 중에 메모리를 할당합니다. 또는 스택 노드에 플래그를 사용하여 사용하지 않음을 표시 할 수 있습니다 (푸시하는 동안 새 플래그를 만들지는 않겠지 만). 원하는 경우 여기에는 너무 복잡합니다.

1

create_stack() 함수에서 메모리를 할당하고 어떤 것으로 초기화하지 않습니다. 그것의 datalower 부분은 여전히 ​​쓰레기입니다.

요소를 팝업 할 때 if (*top_stack == NULL) 조건이 참이되지 않습니다 (가비지 값이 null이 아님). 따라서 모든 노드를 제거한 후 가비지 값을 반환합니다.