简体   繁体   English

C 中自身堆栈实现中的分段 11

[英]Segmentation 11 in own stack implementation in C

Im trying to implement my own stack program, but when I initialize the stack I get the SEGMENTATION FAULT!我试图实现我自己的堆栈程序,但是当我初始化堆栈时,我得到了 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;
}

and here is the struct:这是结构:

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

} intstack_t;

and when I compile it with valgrind I get this: Use of uninitialised value of size 8 ==2744731== at 0x4008B2: stackPush (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== Uninitialised value was created by a stack allocation ==2744731== at 0x400987: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack)当我用 valgrind 编译它时,我得到这个: Use of uninitialised value of size 8 ==2744731== at 0x4008B2: stackPush (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731= = by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== 未初始化的值是由堆栈分配创建的 ==2744731== at 0x400987: main (in /vol /fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack)

==2744731== Conditional jump or move depends on uninitialised value(s) ==2744731== at 0x4007C5: stackPush (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== Uninitialised value was created by a stack allocation ==2744731== at 0x400987: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== 条件跳转或移动取决于未初始化的值 ==2744731== 在 0x4007C5: stackPush (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== 堆栈分配创建了未初始化的值 ==2744731== at 0x400987: main (in /vol/fob -vol2/mi16/sajoseig/Compilerbau/lab1/stack)

==2744731== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==2744731== Bad permissions for mapped region at address 0x4005F4 ==2744731== at 0x4008B2: stackPush (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== 进程以信号 11 (SIGSEGV) 的默认操作终止:转储核心 ==2744731== 地址 0x4005F4 处映射区域的错误权限 ==2744731== 在 0x4008B2:stackPush(在 /vol/fob-vol2/ mi16/sajoseig/Compilerbau/lab1/stack) ==2744731== by 0x4009AB: main (in /vol/fob-vol2/mi16/sajoseig/Compilerbau/lab1/stack)

The problem stems from the fact that you declared the init function to take an intstack_t * but that pointer is copied.问题源于您声明 init function 以获取intstack_t *但该指针已被复制。 So basically the address of the local variable stack is copied into a local variable and then overwritten locally by the assignment of the returned address of malloc , so the stack variable remains unchanged (uninitialized).所以基本上局部变量堆栈的地址被复制到局部变量中,然后通过返回地址malloc的赋值在本地覆盖,因此stack变量保持不变(未初始化)。

A solution is to modify the function to use a double pointer:一种解决方案是将 function 修改为使用双指针:

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

or a reference to pointer.或对指针的引用。

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

But you have to make sure that you're actually using a pointer!但是您必须确保您实际上使用的是指针!

intstack_t *stack;

stackInit(&stack); // for the reference version stackInit(stack) should be called
stackPush(stack, 1);
stackPush(stack, 2);
stackPush(stack, 3);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM