【问题标题】:Error while implementing stack using linkedlist in C在 C 中使用链表实现堆栈时出错
【发布时间】:2017-02-12 14:45:47
【问题描述】:

尝试使用此程序将数据推送到堆栈时,我得到了错误的输出。即使堆栈大小为 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 ....

【问题讨论】:

  • 您在push 中有一个错误。阅读how to debug small programs如何找到它。
  • struct node* newNode = (struct node*)malloc(sizeof(int)); --> struct node* newNode = malloc(sizeof(struct node));
  • struct node* temp = (struct node*)malloc(sizeof(int)); temp = top; top = newNode; top-&gt;next = temp; free(temp); --> newNode-&gt;next = top; top = newNode;
  • @BLUEPIXY - 我真的认为应该将答案发布为作为答案,并且不难阅读格式化的 cmets。
  • printStack 不应更改 top

标签: c data-structures stack


【解决方案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

【讨论】:

    【解决方案2】:

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

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

    #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
    

    【讨论】:

    • push() 可以简化,pop() 应该减少 count
    猜你喜欢
    • 2020-09-12
    • 2012-05-24
    • 2019-03-04
    • 2020-01-16
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 2015-02-14
    相关资源
    最近更新 更多