推入堆栈的问题

时间:2019-01-30 14:30:23

标签: c stack push

对于我用C实现的堆栈,我在推送元素方面存在一些问题。
栈已使用init_size的大小进行了初始化,但是当指针顶部到达栈顶时,当新元素将被推入栈时,我会增加栈的大小。

但是,如果我将struct sqStack sq的引用传递给push函数,则代码可以正常工作;如果我传递sqStack指针* st,则代码在“ * sq-> top ++ = e;”行被错误压缩。在push函数中,如下面的代码所示(尽管有时效果很好)。
对于pop函数,我没有释放所有弹出的元素,可以吗?
谁能帮我找出问题所在?谢谢!

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

#define init_size 10
#define increment 1

typedef struct sqStack
{
    int* top;
    int* base;
    int stack_size;
}sqStack;

int init_stack(sqStack* sq)
{
    if(sq->base==NULL)
    {
       sq->base = (int*)malloc(init_size*sizeof(int));
    }
    if(sq->base==NULL) exit(-1);
    sq->stack_size=init_size;
    sq->top=sq->base;
    return 1;
}
int push(sqStack* sq, int e)
{
    if(sq==NULL) exit(-1);

    if(sq->top-sq->base==sq->stack_size-1)//pointer top reaches the top of the stack
    {
        int* q = (int*)realloc(sq->base,(init_size+increment)*sizeof(int));
        if(q==NULL)  exit(-1);
            sq->base=q;
        sq->top=sq->base+sq->stack_size-1;
            sq->stack_size += increment;

    }
    *sq->top++=e;//Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
    return 1;
}
int pop(sqStack* sq,int* e)
{
    if(sq==NULL) exit(-1);
    if(sq->base==sq->top)  exit(-1);
    sq->top--;
    *e=*sq->top;
    return *e;
}

int empty(sqStack* sq)
{
    if(sq->base==sq->top) return 1;
    else return 0;
}

int main() {

    /*sqStack sq  ;
    init_stack(&sq);

    int a;
    for(int i=0;i<12;i++)
    {
        push(&sq,i+1);
    }
    for(int i=0;i<12;i++)
    {
        printf("%d\n",pop(&sq,&a));
    }*/
    sqStack* st= (sqStack*)malloc(sizeof(sqStack))  ;
    int e;
    init_stack(st);
    for(int i=0;i<12;i++)
    {
        push(st,i+1);
    }
    for(int i=0;i<12;i++)
    {
        printf("%d\n",pop(st,&e));
    }
    return 0;
}

如果要测试参考部分,只需取消注释main中代码的第一部分,而main中第二部分是指针部分。

1 个答案:

答案 0 :(得分:1)

malloc函数不会初始化它分配的内存,它将具有不确定(看似随机)的内容。

这意味着if (sq->base==NULL)函数中的条件init_stack可能为 false ,当您开始取消引用该指针时会导致undefined behavior

init_stack函数中将所有成员都视为“垃圾”,并无条件分配内存。或在调用init_stack之前初始化成员(例如,改为使用calloc


push函数中还有一个逻辑错误,在此函数中,您使用init_size+incrementrealloc调用中计算新的大小。问题在于init_sizeincrement都不会改变,因此,每次调用realloc时,它们的大小将完全相同。

这当然意味着,当您更改sq->stack_size时,从第二次致电realloc起就是错误的。这又导致未定义的行为,因为这样您就有可能超出分配的内存范围。

计算新的大小时,请使用堆栈的当前大小,例如sq->stack_size + increment