如何动态更新结构中的数组?
How can I dynamically update the array within a struct?
所以我有这个结构
#define MAX 128
typedef struct this_struct {
Type items[MAX];
} *SVar;
假设我们创建了这样的东西
SVar first = malloc(sizeof(struct this_struct));
现在,当我将值推入数组并填充到 MAX(即 128)时,我需要动态创建一个新数组,但我不知道如何创建数组,因为数组在里面。
以下是我目前的想法:
- 创建一个新的 SVar names "second" with second->items[MAX *2]
- 免费(第一)
我该怎么做?
一个常用的技巧是做这样的事情:
typedef struct {
int max_items; /* enough memory allocated for so many items */
...
Whatever_type items[1]; /* must be the last member */
} Dyn_array;
...
int n = 127;
Dyn_array *p = malloc(sizeof(Dyn_array) + n*sizeof(p.items[0]);
p->max_items = n + 1;
...
n = 1023;
p = realloc(p, sizeof(Dyn_array) + n*sizeof(p.items[0]);
p->max_items = n + 1;
等等。使用该结构的代码对 items
数组执行越界读取和写入,该数组被声明为仅存储一项。但是,这没关系,因为 C 不进行任何边界检查,并且内存分配策略必须保证始终有足够的 space 可用于 num_items
项。
这样做的典型方法是让您的结构包含三个值:第一个是指向变量数组的指针,第二个是当前分配的数组大小的计数,实际上,您需要第三个项目跟踪您实际使用的数组插槽数。
所以,对于你的结构,它会是这样的:
Type *items;
int item_length; /* Number allocated */
int item_count; /* Number in use */
您最初分配了 "batch" 个条目,比如 100:
first = malloc(sizeof(this_struct));
first->items = malloc(sizeof(Type) * 100);
first->item_length = 100;
first->item_count = 0;
然后您一次添加一个项目。简单来说,就是这样:
first->items[first->item_count] = new_item;
first->item_count += 1;
但实际上你需要确保每次你不会溢出当前分配的 space,所以它 真的 像这样:
if (first->item_count == first->item_length) {
first->item_length += 100;
first->items = realloc(first->items, sizeof(Type) * first->item_length);
}
first->items[first->item_count] = new_item;
first->item_count += 1;
只要您当前分配的 space 足够大,您基本上一次只使用一个插槽。一旦你用完了你分配的所有 space,如果地址 space 中有空间,realloc 将扩展数组,或者它会找到并分配一个新的更大的 [=32] =] 并将所有现有数据移动到新位置(并释放旧的 space)。
实际上,您应该检查 malloc 和 realloc 调用的 return 值。
所以我有这个结构
#define MAX 128
typedef struct this_struct {
Type items[MAX];
} *SVar;
假设我们创建了这样的东西
SVar first = malloc(sizeof(struct this_struct));
现在,当我将值推入数组并填充到 MAX(即 128)时,我需要动态创建一个新数组,但我不知道如何创建数组,因为数组在里面。
以下是我目前的想法:
- 创建一个新的 SVar names "second" with second->items[MAX *2]
- 免费(第一)
我该怎么做?
一个常用的技巧是做这样的事情:
typedef struct {
int max_items; /* enough memory allocated for so many items */
...
Whatever_type items[1]; /* must be the last member */
} Dyn_array;
...
int n = 127;
Dyn_array *p = malloc(sizeof(Dyn_array) + n*sizeof(p.items[0]);
p->max_items = n + 1;
...
n = 1023;
p = realloc(p, sizeof(Dyn_array) + n*sizeof(p.items[0]);
p->max_items = n + 1;
等等。使用该结构的代码对 items
数组执行越界读取和写入,该数组被声明为仅存储一项。但是,这没关系,因为 C 不进行任何边界检查,并且内存分配策略必须保证始终有足够的 space 可用于 num_items
项。
这样做的典型方法是让您的结构包含三个值:第一个是指向变量数组的指针,第二个是当前分配的数组大小的计数,实际上,您需要第三个项目跟踪您实际使用的数组插槽数。
所以,对于你的结构,它会是这样的:
Type *items;
int item_length; /* Number allocated */
int item_count; /* Number in use */
您最初分配了 "batch" 个条目,比如 100:
first = malloc(sizeof(this_struct));
first->items = malloc(sizeof(Type) * 100);
first->item_length = 100;
first->item_count = 0;
然后您一次添加一个项目。简单来说,就是这样:
first->items[first->item_count] = new_item;
first->item_count += 1;
但实际上你需要确保每次你不会溢出当前分配的 space,所以它 真的 像这样:
if (first->item_count == first->item_length) {
first->item_length += 100;
first->items = realloc(first->items, sizeof(Type) * first->item_length);
}
first->items[first->item_count] = new_item;
first->item_count += 1;
只要您当前分配的 space 足够大,您基本上一次只使用一个插槽。一旦你用完了你分配的所有 space,如果地址 space 中有空间,realloc 将扩展数组,或者它会找到并分配一个新的更大的 [=32] =] 并将所有现有数据移动到新位置(并释放旧的 space)。
实际上,您应该检查 malloc 和 realloc 调用的 return 值。