使用C中的链表实现堆栈时出错

时间:2017-02-12 14:45:47

标签: c data-structures stack

尝试使用此程序在堆栈中推送数据时输出错误。即使堆栈大小为5,打印堆栈元素也会运行到无限循环,同时给出错误的值。错误是什么?

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

struct node {
    int data;
    struct node *next;
};

struct node *top = NULL;   

int count = 0;

void push(int num) {
    struct node *newNode = (struct node*)malloc(sizeof(int));
    newNode->data = num;
    newNode->next = NULL;

    if (top == NULL) {
        top = newNode;
    } else {
        struct node *temp = (struct node*)malloc(sizeof(int));
        temp = top;
        top = newNode;
        top->next = temp;
        free(temp);
    }
    count++;
}

int pop() {
    if (top == NULL) {
        printf("\nUnderflow- Stack is empty!");
        return -1;
    }
    struct node *temp = (struct node*)malloc(sizeof(int));
    temp = top;
    top = top->next;
    return temp->data;
}

int stackTop() {
    if (top == NULL) {
        printf("\nStack is empty");
        return -1;
    }
    return top->data;
}

void printStack() {
    if (top == NULL) {
        printf("\nStack is empty. Nothing to print");
    }
    printf("\n");
    while (top !=  NULL) {
        printf("%d ", top->data);
        top = top->next;
    }
}

/* Count stack elements */
void stack_count() {
    printf("\n No. of elements in stack : %d", count);
}

int main(void) {
    int poppedValue, topValue;
    push(1);
    push(2);
    push(3);
    push(4);
    push(5);

    stack_count();

    printStack();

    poppedValue = pop();
    topValue = stackTop();

    printf("\nPop item : %d", poppedValue);
    printf("\nTop Value: %d", topValue);

    return 0;
}

输出:

 No. of elements in stack : 5
5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 0 5 ....

2 个答案:

答案 0 :(得分:1)

您的计划有多个问题:

  • 您为node结构分配了错误的大小:sizeof(int)。在C中不需要转换malloc()的返回值,并将其视为错误的样式。您应该使用这种方法来保证正确的大小:

    struct node *newNode = malloc(sizeof(*newNode));
    

    仅此问题就会导致未定义的行为,这可以解释观察到的问题。

  • 您在邮件前面打印换行符,这不是错误,但会导致输出混乱。您应该将换行符放在邮件的末尾。

  • push函数为temp分配内存但不使用它。 temp会立即被另一个值free过早覆盖,导致同一对象可能多次调用free。这肯定是导致未定义行为的错误。

  • pop函数也会混淆堆叠,并且不会释放顶部节点。

  • 从堆栈中弹出元素时,忘记减少count

  • 函数printStack()修改堆栈top,无法再访问内存。您应该使用临时变量。

以下是修改后的版本:

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

struct node {
    int data;
    struct node *next;
};

struct node *top = NULL;   
int count = 0;

void push(int num) {
    struct node *newNode = malloc(sizeof(*newNode));
    if (newNode == NULL) {
        printf("Memory allocation failed\n");
        return;
    }
    newNode->data = num;
    newNode->next = top;
    top = newNode;
    count++;
}

int pop(void) {
    if (top == NULL) {
        printf("Underflow. Stack is empty!\n");
        return -1;
    } else {
        int data = top->data;
        struct node *temp = top;
        top = top->next;
        free(temp);
        count--;
        return data;
    }
}

int stackTop(void) {
    if (top == NULL) {
        printf("Stack is empty\n");
        return -1;
    }
    return top->data;
}

void printStack(void) {
    if (top == NULL) {
        printf("Stack is empty. Nothing to print\n");
        return;
    }
    struct node *temp = top;
    while (temp !=  NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

/* Count stack elements */
void stack_count(void) {
    printf("No. of elements in stack: %d\n", count);
}

int main(void) {
    int poppedValue, topValue;

    push(1);
    push(2);
    push(3);
    push(4);
    push(5);
    stack_count();
    printStack();
    poppedValue = pop();
    topValue = stackTop();
    printf("Popped item: %d\n", poppedValue);
    printf("Top Value: %d\n", topValue);

    return 0;
}

输出:

No. of elements in stack: 5
5 4 3 2 1
Popped item: 5
Top Value: 4

答案 1 :(得分:0)

您不需要在temp函数中使用push()节点。您只是在使用它来浪费内存。

以下是改进的代码,它运行成功。

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

struct node{
    int data;
    struct node* next;
};
struct node* top = NULL;   

int count = 0;

void push(int num){
    struct node* newNode = (struct node*)malloc(sizeof(struct node));
    newNode->data = num;
    newNode->next =top;
    top=newNode;
    count++;
}

int pop(){
    if(top == NULL){
        printf("\nUnderflow- Stack is empty!");
        return -1;
    }

   int ans=top->data;
   struct node *temp = top;
    top = top->next;
    free(temp);
    count--;
    return ans;
}

int stackTop(){
    if(top == NULL){
        printf("\nStack is empty");
        return -1;
    }
    return top->data;
}


void printStack(){
    struct node *t=top;
    if(t == NULL){
        printf("\nStack is empty. Nothing to print");
    }
    printf("\n");
    while(t !=  NULL){
        printf("%d ",t->data);
        t=t->next;
    }
}

/* Count stack elements */
    void stack_count()
    {
        printf("\n No. of elements in stack : %d", count);
    }

int main(void) {

    int poppedValue, topValue;
    push(1);
    push(2);
    push(3);
    push(4);
    push(5);

    stack_count();


    printStack();

    poppedValue = pop();
    topValue = stackTop();

    printf("\nPop item : %d", poppedValue);
    printf("\nTop Value: %d", topValue);

    return 0;
}

<强>输出

 No. of elements in stack : 5
5 4 3 2 1
Pop item : 5
Top Value: 4