2013-07-31 134 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)条件永远不会变为真(变成垃圾值不为空)等移除所有节点后,它返回垃圾值。