好吧我正在c中制作矢量数据结构(或动态列表)。 这是我的节点结构:
struct vector_node{
void *value;
};
这是我的矢量结构:
struct vector{
int size;
int capacity;
vector_node *start;
vector_node *end;
vector_node **nodes;
};
这是我如何创建和分配向量的内存:
vector* createVector(){
vector *vector = malloc(sizeof(vector));
vector->size = 0;
vector->capacity = 8;
vector->start = NULL;
vector->end = NULL;
vector->nodes = malloc(8*sizeof(vector_node));
int i = 0;
vector->nodes[0]->value = (int) &i;
}
最后两行是我遇到麻烦的地方。似乎每当我尝试初始化值变量时,我都会遇到段错误。
答案 0 :(得分:2)
这里有两级分配。 vector->nodes
是vector_node**
,因此通过取消引用它,您将获得vector_node*
,您尝试通过->value
连续取消引用以获取实例的字段。
但是你如何分配一切? nodes
包含指针而不是真实对象,因此在为指针分配空间之后,还必须单独分配每个节点。
所以分配应该是这样的:
const size_t LENGTH = 8;
vector->nodes = malloc(LENGTH * sizeof(vector_node*)); // note it's vector_node* not vector_node, as we're allocating memory for pointers
for (size_t i = 0; i < LENGTH; ++i)
vector->nodes[i] = malloc(sizeof(vector_node)); // here we're allocating the real object
// now you can correctly have two chained dereferences
vector->nodes[0]->value = (int)&i;
请注意,重新分配也需要两个步骤,顺序相反。
答案 1 :(得分:2)
该行
vector->nodes = malloc(8*sizeof(vector_node));
错了。您需要分配一个vector_node*
数组,因为vector->nodes
类型为vector_node**
。避免此类错误的推荐方法是:
Type* x = malloc(count*sizeof(*x));
对于您的计划,将是:
vector->nodes = malloc(8*sizeof(*(vector->nodes)));
该行
vector->nodes[0]->value = (int) &i;
有几个错误。
vector->nodes[0]
分配内存。int
,这可能会导致地址被截断。vector->nodes[0]->value
的类型为void*
,但您正在尝试为其分配int
。i
的地址存储在将要从函数返回的struct
中。当函数返回时,你将有一个悬空指针。你需要:
vector->nodes[0] = malloc(sizeof(*(vector->nodes[0])));
vector->nodes[0]->value = <some memory that will outlast the function call>;
最后,在返回类型不同于return
的函数中,您没有void
语句。如果调用代码使用类似:
vector* v = createVector();
您的程序将显示未定义的行为。
答案 2 :(得分:1)
要处理您的想法,您需要做一些事情。
更改vector
的定义如下:
struct vector{
int size;
int capacity;
vector_node *start;
vector_node *end;
vector_node *nodes; // <----- this is a pointer that can be offset like an array
};
更改createVector()
的定义,如下所示:
vector* createVector(){
vector *vector = malloc(sizeof(vector));
vector->size = 0;
vector->capacity = 8;
vector->start = NULL;
vector->end = NULL;
vector->nodes = malloc(8*sizeof(vector_node));
int i = 0;
vector->nodes[0].value = (void*) &i; // <----- offset the pointer like an array
// <----- (which is what you allocated for)
}
原因是您为8个vector_node
类型的对象分配了内存,并将基指针分配给vector->nodes
。因为内存包含对象而不是指向对象的指针,所以需要直接偏移指针以获取单个对象。