簡體   English   中英

在 C 中獲取堆棧的分段錯誤錯誤

[英]Getting a segmentation fault error for stack in C

我有一個堆棧結構,它具有執行簡單堆棧操作的動態雙指針 char 數組。 我用 calloc 初始化內存以在數組中具有確定的值。 它在數組大小達到 10 個元素后重新分配空間。

我的代碼的堆棧結構:

typedef struct Stack{
    unsigned int size; //The current number of elements in the stack
    char **stk; //The actual stack represented by an array of strings
    unsigned int arrsize; //To track the size of the array; gets incremented by 10 after limit
}stack;

我的堆棧文件的代碼:

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

#include "stack.h"

#define MULTIPLIER 10
#define MAX_STR 1024

stack *createstack(void){
    stack *s = malloc(sizeof(stack));
    if(s == NULL){
        perror("Failed to malloc!\n");
        return NULL;
    }

    s->size = 0;
    s->arrsize = MULTIPLIER;

    s->stk = calloc(MULTIPLIER, sizeof(char*));
    for (int i = 0; i < MULTIPLIER; i++){
        s->stk[i] = calloc(MAX_STR, sizeof(char));
    }

    return s;
}


int isfull(const stack *s){
    if(s->size % MULTIPLIER == 0){
        return 0;
    }

    else{
        return 1;
    }
}

int isempty(const stack *s){
    if(s->size == 0){
        return 0;
    }
    else{
        return 1;
    }
}

void push(stack *s, char *item){
    if(isfull(s) == 0){
        char **temp = realloc(s->stk, (sizeof(char*)) * (MULTIPLIER + s->arrsize));
        s->arrsize += MULTIPLIER;
        if(temp == NULL){
            perror("Realloc failed!");
        }
    }
    strcpy((s->stk)[s->size], item);
    s->size += 1;
}

char *pop(stack *s){
    if(isempty(s) == 0){
        printf("Stack is empty!");
        return NULL;
    }

    else{
        char *tmp = (char*) malloc(strlen((s->stk)[s->size-1]));
        strcpy(tmp, (s->stk)[s->size-1]);
        s->size -= 1;
        return tmp;
    }
}

void destroy(stack *s){
    if(isempty(s) == 0){
        printf("Stack is already empty!");
    }
    else{
        for(size_t i=0; i < sizeof s; i++){
            free((s->stk)[i]);
        }
        s->size = 0;
        free(s->stk);
        free(s);
    }
}

現在,當我在主函數中做類似的事情時

int main(){

    stack *stek = NULL;
    stek = createstack();

    push(stek, "first");
    push(stek, "second");
    push(stek, "third");

我收到 gcc 的“分段錯誤(核心轉儲)”錯誤。 在檢查 gdb 后,我確認它是由 push() 中的“strcpy”調用引起的。 經過進一步的猜測,我得到了一個想法,即使我使用 calloc 初始化它,也可能沒有將內存分配給 s->stk 數組。 任何有關弄清楚如何解決此錯誤的幫助都將受到贊賞。

編輯:在評論中指出后修復了代碼中的一些小錯誤。

push()重新分配時(它在第一次推送時會不必要地這樣做),它不會使用指向重新分配空間的指針來更新堆棧結構。 假設原始指針在那一點仍然有效是不安全的,因此稍后嘗試取消引用它是不安全的。 這可能是導致段錯誤的缺陷。

此外,當push()擴展堆棧存儲時,它不遵循createstack()的模型,為新元素分配空間以指向它。 這不是您在示例main()看到的段錯誤的原因,但如果您推送了足夠多的元素,這將是一個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM