当前位置: 动力学知识库 > 问答 > 编程问答 >

c - Difference between use of pointer and array with zero elements in structs

问题描述:

How do the two implementations differ:

struct queue {

int a;

int b;

q_info *array;

};

and

struct queue {

int a;

int b;

q_info array[0];

};

网友答案:

The second struct does not use an array of zero elements - this is a pre-C99 trick for making flexible array members. The difference is that in the first snippet you need two mallocs - one for the struct, and one for the array, while in the second one you can do both in a single malloc:

size_t num_entries = 100;
struct queue *myQueue = malloc(sizeof(struct queue)+sizeof(q_info)*num_entries);

instead of

size_t num_entries = 100;
struct queue *myQueue = malloc(sizeof(struct queue));
myQueue->array = malloc(sizeof(q_info)*num_entries);

This lets you save on the number of deallocations, provides better locality of references, and also saves the space for one pointer.

Starting with C99 you can drop zero from the declaration of the array member:

struct queue {
    int a;
    int b;
    q_info array[];
};
网友答案:

These are completely different things:

  • The first contains a pointer to an external array.
  • the second is an inline array that happens to have zero elements.

The reason people do this is it's more space-efficient. You simply over-allocate the memory the struct needs, and then pretend the array has more elements then declared - the compiler won't mind (usually).

It also means you have one less pointer to dereference through, and you can allocate and free the memory for the struct and the array all in one.

Obviously, this trick only works when the array is the last element in the struct.

网友答案:

In the first one there is actually a pointer allocated in struct queue, and sizeof(struct queue) == 2 * sizeof(int) + sizeof(q_info*)

In the second one there is no pointer or anything named array really exists in struct queue, and sizeof(struct queue) == 2 * sizeof(int). This is known as a trick to conveniently reference the data before or later using array. I've used this trick in implementing a memory allocator.

网友答案:

For the zero-sized array member, you can, when you allocate the structure, allocate more memory than the size of struct queue (for example malloc(sizeof(struct queue) + sizeof(q_info) * 10)) to have a contiguous area of memory you can use. Then the array will be part of that memory allocated, and for the example allocation you have ten q_info entries in it.

For the pointer, you have to make two allocations, one for the queue structure, and one for the array member. You of course have to call free twice, once for the array pointer and once for the structure.

However, once allocated both can be used the same.

网友答案:
q_info array[0];

decays to a pointer because of the automatic conversion. However, it is not assignable. You cannot say

array = <some address of an object>;

afterwards.

分享给朋友:
您可能感兴趣的文章:
随机阅读: