仅为阵列的一个元素分配内存

时间:2018-05-16 09:20:25

标签: c arrays pointers linked-list malloc

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

如何在整数数组中执行此操作?

2 个答案:

答案 0 :(得分: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 ArrayList中的标准方法和std::vector<>的大多数实现。这是一个工程妥协。数组的好处(按索引进行O(1)随机访问)和链表(O(1)增长)。

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

(*)副本是内存的原始副本。这对于int来说没什么问题,但是复杂结构'struct'可能无法复制memmove或者需要进一步努力。

答案 1 :(得分:0)

使用动态内存分配概念在运行时确定数组的大小:

int n;
scanf("%d",&n);
ptr = (int*) malloc(n*sizeof(int));

它将返回一个指向第一个可用内存区域的位置的指针,您可以从该位置遍历整个数组。