C语言 C语言中结构体和指针的malloc
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14768230/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
malloc for struct and pointer in C
提问by Pouya
Suppose I want to define a structure representing length of the vector and its values as:
假设我想定义一个表示向量长度及其值的结构:
struct Vector{
double* x;
int n;
};
Now, suppose I want to define a vector y and allocate memory for it.
现在,假设我想定义一个向量 y 并为其分配内存。
struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector));
My search over the internet show that I should allocate the memory for x separately.
我在互联网上的搜索表明我应该单独为 x 分配内存。
y->x = (double*)malloc(10*sizeof(double));
But, it seems that I am allocating the memory for y->x twice, one while allocating memory for y and the other while allocating memory for y->x, and it seems a waste of memory. It is very much appreciated if let me know what compiler really do and what would be the right way to initialize both y, and y->x.
但是,似乎我为 y->x 分配了两次内存,一次为 y 分配内存,另一次为 y->x 分配内存,这似乎是浪费内存。如果让我知道编译器真正做了什么以及初始化 y 和 y->x 的正确方法是什么,我将不胜感激。
Thanks in advance.
提前致谢。
回答by paxdiablo
No, you're notallocating memory for y->xtwice.
不,您不会分配y->x两次内存。
Instead, you're allocating memory for the structure (which includes a pointer) plussomething for that pointer to point to.
相反,你的结构分配内存(其中包括一个指针)加东西该指针指向。
Think of it this way:
可以这样想:
1 2
+-----+ +------+
y------>| x------>| *x |
| n | +------+
+-----+
So you actually need the two allocations (1and 2) to store everything.
因此,您实际上需要两个分配 (1和2) 来存储所有内容。
Additionally, your type should be struct Vector *ysince it's a pointer, and you should never cast the return value from mallocin C since it can hide certain problems you don't want hidden - C is perfectly capable of implicitly converting the void*return value to any other pointer.
此外,您的类型应该是,struct Vector *y因为它是一个指针,并且您永远不应该malloc在 C 中强制转换void*返回值,因为它可以隐藏您不想隐藏的某些问题 - C 完全能够将返回值隐式转换为任何其他指针。
And, of course, you probably want to encapsulate the creation of these vectors to make management of them easier, such as with:
而且,当然,您可能希望封装这些向量的创建,以便更轻松地管理它们,例如:
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);
}
}
By encapsulating the creation like that, you ensure that vectors are either fully built or not built at all - there's no chance of them being half-built. It also allows you to totally change the underlying data structures in future without affecting clients (for example, if you wanted to make them sparse arrays to trade off space for speed).
通过像这样封装创建,您可以确保向量要么完全构建,要么根本没有构建——它们不可能是半构建的。它还允许您将来在不影响客户端的情况下完全更改底层数据结构(例如,如果您想让它们成为稀疏数组以换取速度空间)。
回答by Karthik T
The first time around, you allocate memory for Vector, which means the variables x,n.
第一次,您为 分配内存Vector,这意味着变量x, n。
However xdoesn't yet point to anything useful.
但是x还没有指向任何有用的东西。
So that is why second allocation is needed as well.
这就是为什么还需要第二次分配的原因。
回答by rajneesh
Few points
几点
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));is wrong
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));是错的
it should be struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector));since yholds pointer to struct Vector.
它应该是struct Vector *y = (struct Vector*)malloc(sizeof(struct Vector));因为y持有指向struct Vector.
1st malloc()only allocates memory enough to hold Vector structure (which is pointer to double + int)
1stmalloc()只分配足以容纳 Vector 结构的内存(它是指向 double + int 的指针)
2nd malloc()actually allocate memory to hold 10 double.
第二次malloc()实际分配内存来容纳 10 个双精度。
回答by PQuinn
You could actually do this in a single malloc by allocating for the Vector and the array at the same time. Eg:
您实际上可以通过同时分配 Vector 和数组在单个 malloc 中执行此操作。例如:
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector) + 10*sizeof(double));
y->x = (double*)((char*)y + sizeof(struct Vector));
y->n = 10;
This allocates Vector 'y', then makes y->x point to the extra allocated data immediate after the Vector struct (but in the same memory block).
这会分配 Vector 'y',然后使 y->x 指向 Vector 结构之后的额外分配数据(但在同一内存块中)。
If resizing the vector is required, you should do it with the two allocations as recommended. The internal y->x array would then be able to be resized while keeping the vector struct 'y' intact.
如果需要调整向量的大小,您应该按照建议使用两个分配来进行。然后可以调整内部 y->x 数组的大小,同时保持向量结构 'y' 完整。
回答by Wernsey
In principle you're doing it correct already. For what you want you do need two malloc()s.
原则上你已经做对了。对于你想要的,你需要两个malloc()s。
Just some comments:
只是一些评论:
struct Vector y = (struct Vector*)malloc(sizeof(struct Vector));
y->x = (double*)malloc(10*sizeof(double));
should be
应该
struct Vector *y = malloc(sizeof *y); /* Note the pointer */
y->x = calloc(10, sizeof *y->x);
In the first line, you allocate memory for a Vector object. malloc()returns a pointer to the allocated memory, so y must be a Vector pointer. In the second line you allocate memory for an array of 10 doubles.
在第一行中,您为 Vector 对象分配内存。malloc()返回指向已分配内存的指针,因此 y 必须是 Vector 指针。在第二行中,您为 10 个双精度数组分配内存。
In C you don't need the explicit casts, and writing sizeof *yinstead of sizeof(struct Vector)is better for type safety, and besides, it saves on typing.
在 C 中,您不需要显式强制转换,并且编写sizeof *y而不是sizeof(struct Vector)更适合类型安全,此外,它可以节省打字时间。
You can rearrange your struct and do a single malloc()like so:
您可以重新排列结构并执行malloc()如下操作:
struct Vector{
int n;
double x[];
};
struct Vector *y = malloc(sizeof *y + 10 * sizeof(double));
回答by Andremoniy
When you allocate memory for struct Vectoryou just allocate memory for pointer x, i.e. for space, where its value, which contains address, will be placed. So such way you do not allocate memory for the block, on which y.xwill reference.
当您为您分配内存时,struct Vector只需为指针分配内存x,即为空间分配内存,其中包含地址的值将被放置。所以这样你就不会为块分配内存,在该块y.x上将引用。
回答by oleg_g
First malloc allocates memory for struct, including memory for x (pointer to double). Second malloc allocates memory for double value wtich x points to.
首先 malloc 为 struct 分配内存,包括为 x(指向 double 的指针)的内存。第二个 malloc 为 x 指向的双精度值分配内存。

