malloc在C中的结构和指针

假设我想定义一个表示向量长度和它的值的结构:

struct Vector{ double* x; int n; }; 

现在,假设我想定义一个向量y并为其分配内存。

 struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector)); 

我在互联网上的search显示,我应该分开分配x的内存。

 y->x = (double*)malloc(10*sizeof(double)); 

但是,似乎我为y-> x分配了两次内存,一次为y分配内存,另一次为y-> x分配内存,这似乎是内存浪费。 非常感谢,让我知道什么编译器真的做什么和什么是正确的方式来初始化y和y-> x。

提前致谢。

不,你不会y->x分配两次内存。

相反,你正在为结构(包括一个指针) 加上一些指针指向的内存。

这样想:

  1 2 +-----+ +------+ y------>| x------>| *x | | n | +------+ +-----+ 

所以你实际上需要两个分配( 12 )来存储所有的东西。

另外,你的types应该是struct Vector *y因为它是一个指针,并且你不应该在C中使用malloc返回值,因为它可以隐藏你不想隐藏的某些问题 – C完全能够隐式地将void*将值返回给任何其他指针。

当然,您可能想要封装这些向量的创build,使其更易于pipe理,例如:

 struct Vector { double *data; // no place for x and n in readable code :-) size_t size; }; struct Vector *newVector (size_t sz) { // Try to allocate vector structure. struct Vector *retVal = malloc (sizeof (struct Vector)); if (retval == NULL) return NULL; // Try to allocate vector data, free structure if fail. retVal->data = malloc (sz * sizeof (double)); if (retVal->data == NULL) { free (retVal); return NULL; } // Set size and return. retVal->size = sz; return retVal; } void delVector (struct Vector *vector) { // Can safely assume vector is NULL or fully built. if (vector != NULL) { free (vector->data); free (vector); } } 

通过封装这样的创作,你可以确保vector或者完全构build或者根本不构build – 他们没有半机会的机会。 它还允许您在未影响客户端的情况下完全更改基础数据结构(例如,如果您想使它们成为稀疏arrays以换取空间来换取速度)。

第一次,你为Vector分配内存,这意味着variablesxn

但是, x 还没有指向任何有用的东西

所以这就是为什么第二次分配也是需要的

几点

struct Vector y = (struct Vector*)malloc(sizeof(struct Vector)); 是错的

它应该是struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector)); 因为y持有指向struct Vector指针。

第一个malloc()只分配足够的内存来保存向量结构(这是指向double + int)

第二个malloc()实际分配内存10倍。

原则上你已经做得正确了。 对于你想要的,你需要两个malloc()

只是一些评论:

 struct Vector y = (struct Vector*)malloc(sizeof(struct Vector)); y->x = (double*)malloc(10*sizeof(double)); 

应该

 struct Vector *y = malloc(sizeof *y); /* Note the pointer */ y->x = calloc(10, sizeof *y->x); 

在第一行中,为Vector对象分配内存。 malloc()返回一个指向分配内存的指针,所以y必须是一个Vector指针。 在第二行中,为10个双精度数组分配内存。

在C中,你不需要显式的强制转换,而写sizeof *y而不是sizeof(struct Vector)对于types安全来说是更好的,而且还可以节省input的时间。

你可以重新排列你的结构,并像这样做一个malloc()

 struct Vector{ int n; double x[]; }; struct Vector *y = malloc(sizeof *y + 10 * sizeof(double)); 

当你为struct Vector分配内存的时候,你只需要为指针x分配内存,也就是空间,其中包含地址的值将被放置。 所以这样的方式,你不会分配的内存块, yx将参考。

第一个malloc为struct分配内存,包括x的内存(指向double的内存)。 第二个malloc为double值wtich x指向内存分配。

实际上,你可以在一个malloc中同时分配Vector和数组。 例如:

 struct Vector y = (struct Vector*)malloc(sizeof(struct Vector) + 10*sizeof(double)); y->x = (double*)((char*)y + sizeof(struct Vector)); y->n = 10; 

这将分配Vector'y',然后使y-> x指向Vector结构之后(但是在同一个内存块中)的额外分配数据。

如果需要调整向量的大小,则应该按照build议的那样使用两个分配。 内部y-> x数组可以在保持向量结构“y”完整的情况下被resize。