如何在结构中动态更新数组?

时间:2015-04-05 23:12:28

标签: c arrays stack push pop

所以我有这个结构

#define MAX 128

typedef struct this_struct {
Type items[MAX];
int top;
} *SVar;

让我们说我们创造这样的东西

SVar first = malloc(sizeof(struct this_struct));

现在,当我将值推入数组并填充到128的MAX时,我需要动态创建一个新数组,但我不知道数组是否在内部。

以下是我目前对如何做的想法:

  • 创建一个新的SVar名称" second" with second-> items [MAX * 2]
  • 自由的(第一)

我该怎么做呢?

更新

所以现在我有了这个

#define MAX 128

typedef struct this_struct {
Type *items;
int top
} *SVar;

现在创建第一个分配:

SVar s = malloc(sizeof(struct this_struct));
s->items = malloc(sizeof(Type)*MAX);

现在在另一个函数中动态分配一个新的函数:

SVar second;

if(s->top == MAX- 1) {

    second = malloc(sizeof(*second));
    second->items = malloc(sizeof(Type)*MAX*2);

}

free(s);
s = &second;

这会导致我的程序崩溃。我不知道为什么。

2 个答案:

答案 0 :(得分:0)

通常的做法是做这样的事情:

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不进行任何边界检查,内存分配策略必须保证num_items个项目总有足够的可用空间。

答案 1 :(得分:0)

这样做的典型方法是让你的struct包含三个值:第一个是指向变量数组的指针,第二个是当前分配的数组大小的计数,实​​际上,你需要第三个项目来跟踪您实际使用的阵列插槽数。

所以,使用你的结构,它将是这样的:

Type *items;
int item_length; /* Number allocated */
int item_count;  /* Number in use */

您最初分配了一批“条目”,比如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;

但实际上你需要确保每次你不会溢出当前分配的空间,所以它真的这样:

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;

只要您当前分配的空间足够大,您基本上只使用一个插槽。一旦你使用了你已分配的所有空间,如果地址空间中有空间,realloc将扩展数组,或者它将找到并分配一个新的更大空间并将所有现有数据移动到新位置(并释放旧空间)。

实际上,你应该检查malloc和realloc调用的返回值。