首页 > 解决方案 > 在 C 中实现向量类型

问题描述

我正在实现自己的向量类型,但是因为我不想总是传递对函数的引用(&v),所以我尝试定义一个指向我的向量结构的指针类型。我只是有以下引发分段错误的代码:

typedef struct vector {
    void **items;
    unsigned int capacity;
    unsigned int size;
} vector_st;

typedef vector_st * vector_t;

void vector_init(vector_t v, unsigned int capacity)
{
    v = (vector_t)calloc(1, sizeof(vector_st)); // even using this throws segmentation fault;
    v->capacity = capacity;
    v->size = 0;
    v->items = malloc(sizeof(void *) * v->capacity);
    if (v->items == NULL) {
        exit(EXIT_FAILURE);
    }
}

static void vector_resize(vector_t v, unsigned int capacity)
{
    void **items = realloc(v->items, sizeof(void *) * capacity);
    if (items) {
        v->items = items;
        v->capacity = capacity;
    } else {
        exit(EXIT_FAILURE);
    }
}

void vector_add(vector_t v, void *item)
{
    if (v->capacity == v->size) {
        vector_resize(v, v->capacity * 2);
    }
    v->items[v->size++] = item;
}

unsigned int vector_capacity(vector_t v)
{
    return v->capacity;
}

unsigned int vector_size(vector_t v)
{
    return v->size;
}

void vector_free(vector_t v)
{
    if (v) {
        free(v->items);
        v = NULL;
    }
}

int main()
{
    vector_t v;
    vector_init(v, 4);

    vector_add(v, "Hello");
    vector_add(v, "from");
    vector_add(v, "the");
    vector_add(v, "hole");

    printf("Vector capacity: %u\n", vector_capacity(v));
    printf("Vector size: %u\n", vector_size(v));

    vector_free(v);
    return 0;
}

我知道这是一个普遍的问题,但我似乎无法弄清楚内存错误发生在哪里,而即使我在函数calloc内部调用vector_init,分段错误也会再次发生。

如果我只是将类型定义为typedef vector_st vector_t,意味着没有指针类型,然后将函数定义为接受指针,并将它们的引用传递为&v,那么它可以正常工作,但正如我所说,我的目标是避免&在调用函数时使用。

标签: c

解决方案


在您的 main 函数中,您声明了一个未初始化的指针并将其传递给 vector_init 函数。然后你试图取消引用指针,它是空的或垃圾。您需要先为向量分配内存(而不仅仅是为项目分配内存)。

vector_t vector = (vector_t)malloc(sizeof(vector_st));

[更新]

通常,我写的东西相当于,

vector_t vector_init(unsigned int capacity) {
    vector_t v;

    v = (vector_t)calloc(1, sizeof(vector_st));
    v->capacity = capacity;
    v->size = 0;
    v->items = malloc(sizeof(void*) * capacity);
    if(v->items == NULL) {
        exit(EXIT_FAILURE);
    }

    return v;
}

或者,因为您请求了“通过引用”示例,

void vector_init(vector_t *u, unsigned int capacity) {   
    vector_t v;

    v = *u;

    v = (vector_t)calloc(1, sizeof(vector_st));
    v->capacity = capacity;
    v->size = 0;
    v->items = malloc(sizeof(void*) * capacity);
    if(v->items == NULL) {
        exit(EXIT_FAILURE);
    }
}

我强烈建议不要使用后者:它要求您检查向量是否最初未被分配,如果已分配则处理该情况。


推荐阅读