C语言 Malloc 在结构中的数组和结构
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5465759/
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 of arrays and structs within a struct
提问by system
How does one malloc a struct which is inside another struct?
一个结构体如何分配另一个结构体中的结构体?
I would also like to malloc an array of items inside a struct and then realloc this array when needed, how is this done correctly?
我还想 malloc 结构中的一个项目数组,然后在需要时重新分配这个数组,这是如何正确完成的?
Could you please give an example of declaring a struct and then the above.
你能不能举一个声明结构的例子,然后是上面的。
Im a little unsure of the order of things.
我有点不确定事情的顺序。
Would the array within a struct be freed and then the struct itself, must the struct be malloced when it is created and then its fields be malloced/declared etc?
是否会释放结构中的数组,然后释放结构本身,是否必须在创建结构时对其进行分配,然后对其字段进行分配/声明等?
采纳答案by Sylvain Defresne
A structincluded inside another structis contained by copy, so you would not have to separately malloc it. If the structcontains a pointer to another struct, then you can consider allocating memory for it dynamically.
一个struct包括内部另一个struct被复制包含的,所以你不会有单独的malloc它。如果struct包含指向 another 的指针struct,那么您可以考虑为其动态分配内存。
struct Point2d
{
float x;
float y;
};
struct Rect
{
struct Point2D a;
struct Point2D b;
};
struct LinkedListNode
{
struct LinkedListNode* next;
int value;
};
In struct Rect, the struct Point2Delement are inserted into struct Rectand you don't have to dynamically allocate memory for them. On the contrary in the struct LinkedListNodethe next element is referenced by a pointer and the memory must be dynamically allocated.
在 中struct Rect,struct Point2D元素被插入struct Rect,您不必为它们动态分配内存。相反,struct LinkedListNode下一个元素由指针引用,内存必须动态分配。
The two version are both useful, depending on the situation. There is no correct way to manage memory, it'll depend on your usage.
这两个版本都是有用的,视情况而定。没有正确的方法来管理内存,这取决于您的使用情况。
This same situation occurs in the case of an array. If your array is statically sized, then it can be directly included in the struct. However, if the size can vary, you must store a pointer within the struct.
同样的情况发生在数组的情况下。如果您的数组是静态大小的,那么它可以直接包含在struct. 但是,如果大小可以变化,则必须在struct.
struct Header
{
char magic[4];
unsigned int width;
unsigned int height;
};
struct Buffer
{
char* data;
unsigned int size;
unsigned int capacity;
};
struct Buffer* buffer_init()
{
struct Buffer* buffer = (struct Buffer*)malloc(sizeof(struct Buffer));
buffer->data = 0;
buffer->size = 0;
buffer->capacity = 0;
}
void buffer_grow(struct Buffer* buffer, size_t capacity)
{
if (capacity > buffer->capacity)
{
buffer->data = realloc(buffer->data, capacity);
buffer->capacity = capacity;
}
}
void buffer_append(struct Buffer* buffer, const char* data, unsigned int dataLen)
{
if (dataLen + buffer->size > buffer->capacity)
buffer_grow(MAX(dataLen + buffer->size, buffer->capacity * 2));
memcpy(buffer->data + buffer->size, data, dataLen);
buffer->size += dataLen;
}
The reallocfunction only does a shallow copy, that is pointer value is copied, but not the pointed object. One more time, how you deal with it will depend on your application.
该realloc函数只进行浅拷贝,即拷贝指针值,而不是指向的对象。再一次,您如何处理它将取决于您的应用程序。
回答by Nick Banks
typedef struct _A
{
int *arr;
int arrCount;
} A;
void Construct_A(A *a, int arraySize)
{
a->arrCount = arraySize;
a->arr = (int*)malloc(sizeof(int)*arraySize);
}
void Destruct_A(A *a)
{
free(a->arr);
a->arr = 0;
}
typedef struct _B
{
A *a;
} B;
void Construct_B(B *b, int arraySize_A)
{
b->a = (A*)malloc(sizeof(A));
Construct_A(b->a);
}
void Destruct_B(B *b)
{
Destruct_A(b->a);
free(b->a);
b->a = 0;
}
void main()
{
B b;
Construct_B(&b, 10);
// Use b and b->a
Destruct_B(&b);
}
回答by Tim Cooper
The following is an example of nested structs and arrays in structs. You'll notice how the nested elements must be taken care of before you freethe outer struct or else you'll end up with a memory leak.
以下是结构体中嵌套结构体和数组的示例。您会注意到free在处理外部结构之前必须如何处理嵌套元素,否则最终会出现内存泄漏。
typedef struct Base Base;
struct Base
{
int x;
};
typedef struct Sample Sample;
struct Sample
{
Base base;
int size;
int *arr;
};
// Create the sample struct
Sample *createSample()
{
Sample sample = malloc(sizeof(Sample));
if(sample == NULL)
{
return NULL;
}
sample->base = malloc(sizeof(Base));
if(sample->base == NULL)
{
free(sample);
return NULL;
}
sample->base->x = 0;
sample->size = 0;
sample->arr = NULL;
return sample;
}
// Adding element to the array
void addItemToSample(Sample *sample, int item)
{
if(sample == NULL)
{
return;
}
int *arr = realloc(sample->arr, sizeof(int) * (sample->size + 1));
if(arr == NULL)
{
return;
}
arr[sample->size++] = item;
sample->arr = arr;
}
// Freeing the struct
void freeSample(Sample *sample)
{
// Free deep elements first
free(sample->base);
free(sample->arr);
// Free outer
free(sample);
}
回答by Richard Schneider
typedef struct _A { int i; } A;
typedef struct _B { int j; A a} B;
To get a single B:
要获得一个 B:
B *b = malloc(sizeof(B));
To get an array of B:
要获得 B 的数组:
B *b = malloc(sizeof(B) * arrayLength);
回答by Neil
It's not very readable but sometimes people create a structure with a count member and a final single-element array member. There then is a special factory method that allocates enough space so that you can write to count elements in the array. Obviously the array member can be of any type.
它的可读性不是很好,但有时人们会创建一个包含计数成员和最终单元素数组成员的结构。然后有一个特殊的工厂方法,它分配足够的空间,以便您可以写入对数组中的元素进行计数。显然,数组成员可以是任何类型。
typedef struct {
int count;
int elements[1];
} int_array;
int_array* allocate_int_array(int count)
{
int_array* mem = (int_array*)malloc(sizeof(int_array) + (count - 1) * sizeof(int));
if (mem)
mem->count = count;
return mem;
}

