初始化C结构通过函数

问题描述:

所以我必须用C编写一个vector式的数据结构,一般来说,我犯了这样的结构:初始化C结构通过函数

struct Vector 
{ 
    int length; 
    int *elements; 
}; 

而且功能这样的:

void initialize_vector(struct Vector* vector); 
void create_vector(struct Vector* vector, int* array, int n); 
void remove_vector(struct Vector* vector); 
void vector_add_element(struct Vector* vector, int element); 
void vector_insert(struct Vector* vector, int index, int element); 
void vector_remove_element(struct Vector* vector, int element); 
void vector_remove_at(struct Vector* vector, int index); 

现在,initialize_vector()函数,我想它只是初始化矢量属性为默认值(如length到0和*elements为NULL)。我写的是这样的:

void initialize_vector(struct Vector* vector) 
{ 
    vector->elements = NULL; 
    vector->length = 0; 
} 

我想检查是否正常工作,所以我写了这段代码:

#include <stdio.h> 
#include "vector.h" 


int main(int arc, char** argv) 
{ 
    struct Vector* vec; 
    initialize_vector(vec); 
    printf("%d\n", vec->length); 
    return 0; 
} 

我得到了著名Segmentation fault,所以我查了GDB,和当然,当一切都拧紧了这一行:vector->elements = NULL;

我不知道问题出在哪里。我宣布了一个矢量,我猜想它正确地传递给它,并且它弄得一团糟。我知道这可能是微不足道的,我会被一些超级计算机专家大大降低,但是,嘿,他没有任何问题没有任何问题。

+1

1:更改'结构矢量* VEC;'到'结构向量VEC;''initialize_vector(VEC);'到'initialize_vector(&vec);'将指针传递函数的结构 2:创建一个实例来一个带有malloc()的Vector – Grifplex

+0

没有为'struct'分配内存 –

+0

“我声明了一个向量” - 不!你声明并定义了一个**指针**给struct Vector,指针不是相同类型它指向详细信息可在编程关键“当一切都搞砸了是这条线的那一刻......” - !你搞砸了更早的编译器警告是因为好玩启用他们,并留意 – Olaf

你没有声明一个向量,你声明了一个指针到一个向量。该指针未初始化,因此试图取消引用它将调用undefined behavior

创建struct Vector,并通过其地址:

struct Vector vec; 
initialize_vector(&vec); 
printf("%d\n", vec.length); 

如果你想在同一时间分配的struct Vector空间,改变函数来调用malloc并返回指针:

struct Vector *initialize_vector() 
{ 
    struct Vector *vector = malloc(sizeof(*vector)); 
    if (!vector) { 
     perror("malloc failed"); 
     exit(1); 
    } 
    vector->elements = NULL; 
    vector->length = 0; 
    return vector; 
} 

... 

struct Vector *vector = initialize_vector(); 
+1

我有!!删除我的答案。谢谢你帮助我理解。为什么对内存的引用丢失? –

+0

是的,确切地说,完美地工作,谢谢。方式,最好的方式来存储它,创建一个向量,创建一个向量的指针并操作它的指针,或者把它保持为一个常规向量,并且总是通过地址传递它? 或者按照@Coldspeed的建议,使用'mallloc()'来使它存在 – FrynioS

+1

@Coldspeed你正在修改一个局部变量。该功能以外的修改不可见。 – dbush

dbush给了一个很好的答案,所以我不会给你代码。相反,我会给出一个C指针的解释,以免再次遇到相同的错误。

struct Vector * vec;

声明一个指向结构体的指针,而不是实际的结构体。什么是指针?它是一个包含地址的变量。因此,所有指针,无论它们是int *,char *,char **还是struct Vector *,都具有相同的大小(通常取决于体系结构的32位或64位)。声明指针的类型仅用于取消引用指针(获取存储在该内存地址中的数据)。这是有道理的,解除引用void *指针会导致错误。回到上面的语句中,这个声明用英文表示为:“vec是一个变量,可以保存结构向量的地址”。但是,现在vec并没有一个有效的地址。

在为指针变量赋值之前,存储在该变量中的地址是垃圾,我们称之为未初始化的变量。在你的情况下,你然后将这个未初始化的地址传递给initialize_vector(),它尝试访问存储在该地址中的值。但正如我们所知,这个地址是垃圾。这给了seg故障。

另一件需要指出的是,在编写这些功能时,您需要做出设计决定。你是否想要struct Vectors存放在堆上(通过调用malloc)或堆栈上?堆允许更多的灵活性,但它也要求程序员仔细跟踪正在使用的指针,以避免内存泄漏,这可能会变得棘手。如果我是你,我会从堆栈中的对象开始,然后将他们的地址传递给修改函数。 dbush的第一个答案。这样你就不必担心调用free()。

+0

是的,但后来我需要'malloc()',因为实验室的人告诉我们,我们的结构必须动态分配:D – FrynioS