Struct member [ array vs pointer ]
What is the benefit of declaring a C structure member as in array of size 1 instead of a pointer开发者_开发百科 :
struct {
a_struct_t a_member[1];
...
}b_struct;
Thanks in advance
In a typical case, a structure with a member that's declared as an array of one item will have that member as the last item in the struct. The intent is that the struct will be allocated dynamically. When it is allocated, the code will allocate space for as many items as you really want/need in that array:
struct X {
time_t birthday;
char name[1];
};
struct X *x = malloc(sizeof(*x) + 35);
x->birthday = mktime(&t);
strcpy(x->name, "no more than 35 characters");
This works particularly well for strings -- the character you've allocated in the struct gives you space for the NUL terminator, so when you do the allocation, the number of characters you allocate is exactly the strlen()
of the string you're going to put there. For most other kinds of items, you normally want to subtract one from the allocation size (or just live with the allocated space being one item larger than is strictly necessary).
You can do (sort of) the same thing with a pointer, but it results in allocating the body of the struct separately from the item you refer to via the pointer. The good point is that (unlike the method above) more than one item can be allocated dynamically, where the method above only works for the last member of the struct.
What you describe are two different things entirely. If you have a pointer as a member:
a_struct_t* a_member;
then it is simply a pointer. There is no memory allocated inside of the struct to hold an a_struct_t
. If, on the other hand, you have an array of size 1:
a_struct_t a_member[1];
then your struct actually has an object of type a_struct_t
inside of it. From a memory standpoint, it isn't much different from just putting an object of that type inside the struct:
a_struct_t a_member;
From a usage standpoint, an array requires indirection to access the one element (i.e., you need to use *a_member
instead of a_member
).
"Array of size 1 instead of a pointer"? Sorry, but I don't see how this quiestion can possibly make sense. I would understand if you asked about "array of size 1 instead of an ordinary member (non-array)". But "instead of a pointer"? What does pointer have to do with this? How is it interchangeable with an array, to justify the question?
If what you really wanted to ask is why it is declared as an array of size 1 instead of non-array as in
struct {
a_struct_t a_member;
} b_struct;
then one possible explanation is the well-known idiom called "struct hack". You might see a declaration like
struct {
...
a_struct_t a_member[1];
} b_struct;
used to implement an array of flexible size as the last member of the struct object. The actual struct object is later created within a memory block that is large enough to accomodate as many array elements as necessary. But in this case the array has to be the last member of the struct, not the first one as in your example.
P.S. From time to time you might see "struct hack" implemented through an array of size 0, which is actually a constraint violation in C (i.e. a compile error).
So I think it's been stated that the main difference between pointers and arrays is that you have to allocate memory for pointers.
The tricky part about your question is that even as you allocate space for your struct, if your struct contains a pointer you have to allocate a SECOND time for the pointer, but the pointer itself would be allocated as part of the struct's allocaiton.
If your struct contained an array of 1 you would not have to allocate any additional memory, it would be stored in the struct (which you still have to allocate).
These are different things.
Such member's name is an address of allocated memory, allocated inside the struct instance itself.
精彩评论