1

假设我已经为一个数组分配了空间

double *array;
array=malloc(100*sizeof(double));

我做了一些过程,最后我不再需要前 10 个元素,我尝试了这个realloc

array=realloc(array+10, 90*sizeof(double));

但我得到一个无效的指针错误:

*** glibc detected *** ./temp: realloc(): invalid pointer:...

如何从一开始就缩小数组?

4

2 回答 2

3

首先,为了缩小数组而重新分配数组并不是一个好主意。如果你这样做很多次,它可能会导致内存碎片。realloc()必要时用于扩展数组。(当然,这也不会防止碎片化,但如果你使用realloc()更少,那会有所帮助。)


也就是说,如果您仍然想缩小数组:正如文档在提出这个问题之前您已经阅读过,amirite?realloc())所说,您必须调用malloc(). 不是那个指针加十,不是那个指针乘以欧拉常数,不是那个指针减去当前月份的天数,没有别的,就是那个指针。

所以你必须先移动元素,然后重新分配数组。但这涉及将元素复制到临时缓冲区,如下所示:

double *tmp = malloc(90 * sizeof(*tmp));
memcpy(tmp, array, 90 * sizeof(*tmp));

double *guard = realloc(array, 90 * sizeof(*array));
if (!guard) {
    // realloc() failed
    abort(); // whatever
}

array = guard;
memcpy(array, tmp, 90 * sizeof(*tmp));

所以这并没有更好,您可以free()在复制其内容并将新获得的指针分配给array.

于 2013-07-27T08:41:23.973 回答
1

阅读void* realloc (void* ptr, size_t size);::

重新分配内存块

更改 ptr 指向的内存块的大小。

该函数可以将内存块移动到新位置(其地址由函数返回)。

即使将块移动到新位置,内存块的内容也会保留到新旧大小中的较小者。如果新大小较大,则新分配部分的值是不确定的。

参数:
ptr
指向先前使用malloccalloc或分配的内存块的指针realloc。或者,这可以是一个空指针,在这种情况下分配一个新块(就像malloc被调用一样)。

不,您不能像这样重新分配元素,realloc需要malloc()/calloc()函数返回的收件人

所以你可以做的是从数组中删除前 10 个数字,然后调用 reallocate。

在许多实现中,通过调用收缩操作realloc()会导致堆中保留大小的更改并且不会移动内存。(是的,但内存管理可能会移动以填充碎片区域)。

于 2013-07-27T08:34:58.420 回答