2013-07-31 135 views
0

我通過使用指針實現堆棧。它正在編譯和工作,但是當堆棧爲空時它不會下溢。它給了我一些垃圾價值。我認爲這個問題是create_stack函數中的問題。無論從堆棧中彈出多少數據都是奇怪的,我都不會收到段錯誤。堆棧由指針在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的指針'來注意函數中分配的內存不會泄漏。分配的內存被放置在堆棧上。但正如我所說,我認真認爲這個功能存在一個錯誤。它似乎正在凝視我的臉,但我不能放置它。 –

+1

分配原因返回一個垃圾值,並在後續的彈出操作後,它可能是未定義行爲的原因。 –

回答

2

當您創建堆棧時,爲節點分配空間 - 並且不要填充任何內容。因此,在調用create_stack()之後,堆棧中已經有了一個空白節點。我猜你不希望這樣,這樣做只是

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

會工作得很好。你在push()調用期間分配內存,無論你在函數中檢查了top_stack == NULL。或者,你可以在你的堆棧節點中有一個標誌來表明它沒有被使用(然後在推動過程中你不會創建一個新的),但是這對於你想要的東西來說太複雜了。

1

create_stack()函數你分配內存,並沒有初始化它的任何東西。其datalower部分仍然是垃圾。

當你彈出元素if (*top_stack == NULL)條件永遠不會變爲真(變成垃圾值不爲空)等移除所有節點後,它返回垃圾值。