C中自己的堆栈实现中的细分11

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

我正在尝试实现自己的堆栈程序,但是当我初始化堆栈时遇到了SEGMENTATION FAULT!

extern int stackInit(intstack_t* self){
self = malloc(sizeof(intstack_t));
if(self == NULL){
    fprintf(stderr,"Out of memory.");
    free(self);
    exit(-1);
}

self->bottom = malloc(MINIMUM_SIZE * sizeof(int));
if(self->bottom == NULL){
    fprintf(stderr,"Out of memory.");
    free(self->bottom);
    exit(-1);
}
self->top = self->bottom - 1;
self->allocated_top = self->bottom + MINIMUM_SIZE -1;
return 0;
}

int main()
{
intstack_t stack;

stackInit(&stack);
stackPush(&stack, 1);
stackPush(&stack, 2);
stackPush(&stack, 3);
}

extern void stackPush(intstack_t* self, int i){

//check if the stack is full and double its size if so.
if(self->top == self->allocated_top){
    ptrdiff_t total = self->top - self->bottom +1;
    ptrdiff_t new_total = GROWTH_FACTOR + total;
    self->bottom = realloc(self->bottom, new_total * sizeof(int));
    if(self->bottom == NULL){
        fprintf(stderr,"Out of memory.");
        free(self->bottom);
        exit(-1);
    }
    self->top = self->bottom + total - 1;
    self->allocated_top = self->bottom + new_total - 1;
}
*(++self->top) = i;
}

这是结构:

typedef struct
{
int* bottom;
int* top;
int* allocated_top;

} intstack_t;

并且当我用valgrind编译时,我得到了:使用大小为8的未初始化值== 2744731 == at 0x4008B2:stackPush(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack)== 2744731 ==通过0x4009AB:main(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack中)== 2744731 ==未初始化的值是由堆栈分配创建的== 2744731 == at 0x400987:main(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack)

== 2744731 ==条件跳转或移动取决于未初始化的值== 2744731 == at 0x4007C5:stackPush(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack)== 2744731 ==通过0x4009AB:main(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack中)== 2744731 ==未初始化的值是由堆栈分配创建的== 2744731 == at 0x400987:main(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack)

== 2744731 ==进程终止于信号11(SIGSEGV)的默认操作:转储核心== 2744731 ==地址0x4005F4的映射区域的权限错误== 2744731 == at 0x4008B2:stackPush(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack)== 2744731 ==通过0x4009AB:main(在/ vol / fob-vol2 / mi16 / sajoseig / Compilerbau / lab1 / stack中)

c segmentation-fault valgrind
1个回答
1
投票

问题源于以下事实:您声明init函数采用intstack_t *,但是该指针已被复制。因此,基本上,将局部变量堆栈的地址复制到局部变量中,然后通过分配返回的malloc地址在本地进行覆盖,因此stack变量保持未绑定状态(未初始化)。

一种解决方案是将函数修改为使用双指针:

extern int stackInit(intstack_t **self) {
// instead of self you write (*self)
}

或对指针的引用。

extern int stackInit(intstack_t *&self) {
// the function remain unchanged
}

但是您必须确保您实际上正在使用指针!

intstack_t *stack;

stackInit(&stack); // for the reference version stackInit(stack) should be called
stackPush(stack, 1);
stackPush(stack, 2);
stackPush(stack, 3);
© www.soinside.com 2019 - 2024. All rights reserved.