【问题标题】:Memory allocation for just one element of array只为数组的一个元素分配内存
【发布时间】:2026-02-11 20:35:01
【问题描述】:

我无法在运行时确定数组大小,因为它会有依赖关系。所以我需要为一个元素分配内存。就像我可以说的链表一样。

如何在整数数组中做到这一点?

【问题讨论】:

  • 你不能在一个数组中的所有元素都分配在一起
  • 嗨,我在回答中添加了一些注释,您可能会发现将指针重定向到移动的数组中很有用。可能不相关。
  • @Persixty 感谢您提供的信息。他们帮了我很多。

标签: c arrays pointers linked-list malloc


【解决方案1】:

我想你是说你想一次“增长”一个数组。

realloc() 是 C 中整数数组 (*) 的一个选项。

size_t n=0;//Length of array.
int* arr=NULL;

//Some code...

//Now we want to grow our array
//This is probably in a loop or called in a function from a loop (not shown).
++n;
int* temp=realloc(arr,n*sizeof(int));
if(temp==NULL){
    free(arr);
    return 1;//Error...
}
arr=temp;

//More code....

//Now we're done with arr.
free(arr);

在第一遍arrNULLrealloc(NULL,..) 就像malloc()。 但是在随后的传递中,当arr 不是NULL 时,realloc 会尝试“就地”增长数组(如果内存在其末尾可用)。如果没有,它会尝试在其他地方分配空间,然后复制现有数据并释放旧位置。 如果它不能重新分配,它什么也不做并返回NULL,所以你有责任释放那个空间(free(arr))。

注意:始终将 realloc() 的返回值分配给临时变量(即不是第一个参数)。 否则,如果分配失败,您已经泄漏了现有内存。

realloc 是一种快速技巧,可以减少增长数组所需的分配和复制量 - 替代方法。

如果这还不够有效,正常的模型是跟踪“容量”和“长度”之类的东西。

 const size_t chunk=10;
 size_t cap=0;
 size_t n=0;
 int* arr=NULL;

 ++n;
 if(n>cap){
     cap+=chunk;
     int* temp=realloc(arr,cap);
     if(temp==NULL){
         free(arr);
         return 1;//Error
     }
 }

 //Later...
 free(arr);

这样做的好处是您可以调整需要多少“备用”开销来调整重新分配发生的频率。另一个策略是cap=cap*2;,尽管空间显然呈指数增长!可以写一本关于这个经典策略的书。通常可以一次性为大多数实际情况分配足够的资源,但仍然可以处理异常情况。

如果您知道数组现在已满,您还可以选择重新分配以恢复可用空间。

如果不明显,如果数组被移动,任何指向它或指向它的指针都必须重定向。这是仅使用[.] 对其进行索引的论点。在进行重定向之前,您需要保留旧位置。 ptr=temp+(ptr-arr) 使ptr 指向元素ptr 指向的新位置。

这是在 Java ArrayListstd::vector<> 的大多数实现中找到的标准方法。这是工程上的妥协。数组(O(1) 通过索引随机访问)和链表(O(1) 增长)的好处。

它仍然是渐近线性的,但在实际情况下提供了很大的好处。计算机科学关注的是渐近率和在有限真实案例中具有实际值的工程。

(*) 该副本是内存的原始副本。这对 int 来说很好,但复杂的结构“struct”可能无法复制到 memmove 或采取进一步的努力。

【讨论】: