无论堆栈中压入的值如何,都会弹出相同的值

问题描述 投票:0回答:8

我正在编写一个简单的堆栈程序(主函数只是确定用户要求你做什么)。

但是,它有一个“错误”,它只是继续“弹出”相同的值(实际上并没有弹出任何内容)。

我是否错误地使用了结构和指针?或者这是一个不太明显的编码错误?

#include <stdio.h>

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

void push(int);
void pop();

int main(void)
{
    int command = 0;
    
    while (command != 3)
    {
        printf("Enter your choice:\n1) Push integer\n2) Pop Integer\n3) Quit.\n");
        scanf("%d",&command);
        if (command == 1)
        {
            // push
            int num;
            scanf("%d",&num);
            push(num);
        }
        else
        {
            if (command == 2)
            {
                pop();
            }
            else
            {
                if (command != 3)
                {
                    printf("Command not understood.\n");
                }
            }
        }
    }

    return 0;
}

void push (int x)
{
    struct node newNode;
    newNode.data = x;
    newNode.prev = NULL;
    newNode.next = &first;
    first = newNode;
    printf("%d was pushed onto the stack.\n", first.data);
}

void pop()
{
    if (first.data == '\0')
    {
        printf("Error: Stack Empty.\n");
        return; 
    }
    printf("%d was popped off the stack.\n", first.data);
    first = *(first.next);
    first.prev = NULL;
}
c stack
8个回答
5
投票

first 应该是一个指针。将其更改为 struct node *first;

在主初始化中first=NULL;

更改您的推送/弹出操作,如下所示,

void push (int x)
{
    struct node *newNode;// It should be a pointer
newNode = (struct node *)malloc(sizeof(struct node));
    newNode->data = x;
    //newNode.prev = NULL; // You don't need this
    newNode->next = first;
    first = newNode;
    printf("%d was pushed onto the stack.\n", first->data);
}

void pop()
{
struct node *prevPtr;
    //if (first.data == '\0')
    if (first == NULL) // check if stack is empty
    {
        printf("Error: Stack Empty.\n");
        return; 
    }

    printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
    first = first->next;

free(prevPtr);
}

4
投票

问题在于

first
是单个全局
node
,并且它是您拥有的唯一
node
(除了您对
node
的调用中的临时本地
push
)。

这一行:

    first = newNode;

只需将

newNode
的内容复制到
first
中;由于
newNode.next
指向
first
,这意味着现在
first.next
指向
first
,所以你有一个单元素循环链表。

同样,这一行:

    first = *(first.next);

只需将

*(first.next)
的内容复制到
first
中;这是一个无操作,因为(由于上述原因),
*(first.next)
is
first

要解决这个问题,您实际上需要使用

malloc
(和
free
)动态创建节点。你的全局
first
变量应该是一个指针 -
node *
- 始终指向堆栈的顶部元素。 (更好的是,您的
push
pop
函数应该将
first
作为参数,而不是将其作为全局变量。这些函数不需要只允许单个堆栈存在。)


2
投票

&first
有什么价值?提示,它总是相同的,因为
first
是静态分配的。即使改变结构体的内容,地址也不会改变。这可能会告诉您为什么
push
存在错误。如果您要拥有不同大小的结构,则需要使用
malloc
free


1
投票

当您必须自己管理内存时(正如 C 要求您做的那样),您需要了解称为堆栈和堆的内存区域之间的区别。 (这个“堆栈”与您在程序中创建的数据结构略有不同。)

您的

push()
函数正在堆栈上创建一个新节点;当函数退出时,堆栈将被弹出,并且新节点占用的内存可供争夺。您看到输入的值是因为您的程序非常简单。如果它调用执行其他操作的其他函数,它们几乎肯定会覆盖堆栈的该部分,当您调用
pop()
时,您会看到垃圾。

正如其他人所指出的,您需要使用函数

malloc()
free()
,它们从堆而不是堆栈中为您提供内存。


1
投票

如果要使用链表创建堆栈,请将

first
变量设置为指针。然后,当您将新节点推入堆栈时,通过 malloc() 在堆内存上分配来创建新节点。我知道你打算用它来指向堆栈的顶部。对吗?

在您的代码中,

first
变量被新节点覆盖,因为它不是指针变量而是值变量。这使得结果丢失了堆栈的顶部节点。


1
投票
void pop()
{
struct node *prevPtr;
//if (first.data == '\0')
if (first == NULL)
{
    printf("Error: Stack Empty.\n");
    return; 
}

printf("%d was popped off the stack.\n", first->data);
prevPtr = first;
first = first->next;

free(prevPtr);
}

0
投票
#include <stdio.h>
#include <stdlib.h>

struct stack {
  int size;
  int top;
  int *arr;
};

int isEmpty(struct stack* ptr){
    if(ptr->top == -1){
        return 1;
    }
    else{
         return 0;
    }
}

int isFull(struct stack* ptr){
    if(ptr->top == ptr->size-1){
        return 1;
    }
    else{
         return 0;
    }
}

int display(struct stack *s){
    for(int i = s->top; i >= 0; i--){
        printf("%d\n", s->arr[i]);
    }
}

int main(){
    struct stack *s = (struct stack*)malloc(sizeof(struct stack));
    s->size = 80;
    s->top = -1;
    s->arr = (int *)malloc(s->size * sizeof(int));
    
    s->top ++;
    s->arr[s->top] = 1;
    s->top ++;
    s->arr[s->top] = 2;
    s->top ++;
    s->arr[s->top] = 3;
    
    display(s);
    // if(isEmpty(s)){
    //     printf("Stack Empty!");
    // }
    // else{
    //     printf("Stack not empty!");
    // }
    
    
    
}

-2
投票
#include<stdio.h>

# define max 10

int stack[max],top=-1,size=0;

void push()

{

     if(top==(max-1))

     {

         printf("stack full\n");

     }

     else

     {

    top++;

    printf("enter the value which you want to insert\n");

    scanf("%d",&stack[top]);

     }

}

void pop()

{

int str;

if(top==-1)

        {

         printf("stack empty\n");

     }

     else

        {


    str=stack[top];

     top--;

    printf("the removed element is %d\n",str);

        }

}

void display()

{

 int i;

    for(i=0;i<top;i++)

    {

        printf("%d\n",stack[i]);

    }

}

void main()

{ 

int enter,x;

    do

    {

        printf("enter 1 for push the element in the array\n");

        printf("enter 2 for pop the element in the array\n");

        printf("enter 3 for display the element in the array\n");

        scanf("%d",&enter);

        switch(enter)

        {

        case 1:push();

        break;

        case 2:pop();

        break;

        case 3:display();

        break;

    default:

        printf("invalid syntax");

        }


         printf("for continue press 0\n");

        scanf("%d",&x);

    }

while(x==0);

}
© www.soinside.com 2019 - 2024. All rights reserved.