c - 在 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
,那么它可以正常工作,但正如我所说,我的目标是避免&
在调用函数时使用。
解决方案
在您的 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);
}
}
我强烈建议不要使用后者:它要求您检查向量是否最初未被分配,如果已分配则处理该情况。
推荐阅读
- jenkins - Jenkins 的 Generic Webhook Trigger Plugin:在除 master 之外的所有分支上触发
- c# - Entity Framework Core - 动态过滤
- flat-file - BeanIO:从平面文件读取的一对多关系
- node.js - 节点:创建面板以启动停止节点服务器
- sql-server - 在 Go 中同时获取多个结果集和输出,但是如何先扫描输出?
- arrays - 在heredoc中使用存储为Bash数组的命令
- python - 请解释一下CEFPython3
- javascript - 除非打开或关闭兼容模式,否则 IE11 中不会加载 Javascript
- apache-spark - 更改 spark 数据帧分区写入的路径
- java - 可选接口问题