2016-03-02 63 views
0

我正在嘗試創建一個程序,該程序允許用戶使用push,pop和peek命令創建堆棧數據結構。但是,每當嘗試使用push命令時,我都會遇到分段錯誤!我不知道爲什麼它不起作用,因爲我一定要在堆棧結構上使用malloc。 peek和pop命令正在工作(據我所知)。任何幫助?Segmenation Fault - 處理堆棧數據結構

#include<stdlib.h> 
#include<stdio.h> 
#include "stack.h" 

int mainMenuChoice, pushValue; 


void mainMenu() { 
    printf("\nEnter your option: \n"); 
    printf("1. Push\n"); 
    printf("2. Pop\n"); 
    printf("3. Peek\n"); 
    printf("4. Exit\n"); 
    scanf("%d", &mainMenuChoice); 
} 

Stack * initializeStack() { 
    Stack *new_stack; 
    int capacity = 100; 
    new_stack = (Stack *)malloc(sizeof(Stack)); 
    new_stack->items = (int *)malloc(sizeof(int)*capacity); 
    new_stack->size = 0; 
    return new_stack; 
} 

void push(Stack *new_stack, int item) { 
    new_stack->items[new_stack->size++] = item; 
} 
void pop(Stack *new_stack) { 
    if(new_stack->size == 0) { 
     printf("The stack is empty, you can't pop any items!\n"); 
    } else { 
     new_stack->size--; 
    } 
} 
int peek(Stack *new_stack) { 
    if(new_stack->size == 0) { 
     printf("The stack is empty.\n"); 
    } else { 
     return new_stack->items[new_stack->size-1]; 
    } 
} 


void menuOptions(int option) { 
    Stack *new_stack = initializeStack(); 
    if(option == 1) { 
     Stack *new_stack; 
     printf("Enter an element to push: "); 
     scanf("%d", &pushValue); 
     push(new_stack, pushValue); 
     mainMenu(); 
     menuOptions(mainMenuChoice); 
    } else if(option == 2) { 
     pop(new_stack); 
     mainMenu(); 
     menuOptions(mainMenuChoice);   
    } else if(option == 3) { 
     peek(new_stack); 
     mainMenu(); 
     menuOptions(mainMenuChoice); 
    } else if(option == 4) { 
     printf("Exiting...\n"); 
     exit(0); 
    } else { 
     printf("Invalid input, please try again!\n"); 
     mainMenu(); 
     menuOptions(mainMenuChoice); 
    } 
} 

void program() { 
    mainMenu(); 
    menuOptions(mainMenuChoice);  
} 

而且,這是我是如何構造的堆棧:

typedef struct Stack { 
    int size; 
    int *items; 
}Stack; 

非常感謝你提前,本人不勝感激!

+0

1)'如果(選項= = 1){stack_new_stack;':刪除'Stack * new_stack;'2)'menuOptions(mainMenuChoice);':當遞歸調用'Stack * new_stack = initializeStack();','new_stack'是一個單獨的變量呼叫。 – BLUEPIXY

+0

@BLUEPIXY不會遞歸調用Stack * new_stack = initializeStack();'導致堆棧不斷重置? – msafi

+0

這是另一個變量。 – BLUEPIXY

回答

1

我簡化了一些東西。你有太多的遞歸調用和new_stack被重新定義[但不是重新分配]。你仍然有更多的工作要做(例如peek返回一個值,但pop沒有)

下面的代碼[請原諒無償風格清理]:

#include <stdlib.h> 
#include <stdio.h> 
//#include "stack.h" 

typedef struct Stack { 
    int size; 
    int *items; 
} Stack; 

int mainMenuChoice; 
int pushValue; 
Stack *top_stack; 

void 
mainMenu() 
{ 
    printf("\nEnter your option: \n"); 
    printf("1. Push\n"); 
    printf("2. Pop\n"); 
    printf("3. Peek\n"); 
    printf("4. Exit\n"); 
    scanf("%d", &mainMenuChoice); 
} 

Stack * 
initializeStack() 
{ 
    Stack *new_stack; 
    int capacity = 100; 

    new_stack = (Stack *) malloc(sizeof(Stack)); 
    new_stack->items = (int *) malloc(sizeof(int) * capacity); 
    new_stack->size = 0; 

    return new_stack; 
} 

void 
push(Stack *new_stack, int item) 
{ 
    new_stack->items[new_stack->size++] = item; 
} 

void 
pop(Stack *new_stack) 
{ 
    if (new_stack->size == 0) { 
     printf("The stack is empty, you can't pop any items!\n"); 
    } 
    else { 
     new_stack->size--; 
    } 
} 

int 
peek(Stack *new_stack) 
{ 
    if (new_stack->size == 0) { 
     printf("The stack is empty.\n"); 
     return -1; 
    } 
    else { 
     return new_stack->items[new_stack->size - 1]; 
    } 
} 

void 
menuOptions(Stack *new_stack,int option) 
{ 

    if (option == 1) { 
     printf("Enter an element to push: "); 
     scanf("%d", &pushValue); 
     push(new_stack, pushValue); 
    } 
    else if (option == 2) { 
     pop(new_stack); 
    } 
    else if (option == 3) { 
     peek(new_stack); 
    } 
    else if (option == 4) { 
     printf("Exiting...\n"); 
     exit(0); 
    } 
    else { 
     printf("Invalid input, please try again!\n"); 
    } 
} 

int 
main() 
{ 

    top_stack = initializeStack(); 

    while (1) { 
     mainMenu(); 
     menuOptions(top_stack,mainMenuChoice); 
    } 

    return 0; 
}