【发布时间】:2010-03-19 18:41:15
【问题描述】:
看这个例子:
int *array = malloc (10 * sizeof(int))
有没有办法只释放前 3 个块?
或者有一个带有负索引的数组,或者不以 0 开头的索引?
【问题讨论】:
看这个例子:
int *array = malloc (10 * sizeof(int))
有没有办法只释放前 3 个块?
或者有一个带有负索引的数组,或者不以 0 开头的索引?
【问题讨论】:
您不能直接释放前 3 个块。您可以通过重新分配更小的数组来做类似的事情:
/* Shift array entries to the left 3 spaces. Note the use of memmove
* and not memcpy since the areas overlap.
*/
memmove(array, array + 3, 7);
/* Reallocate memory. realloc will "probably" just shrink the previously
* allocated memory block, but it's allowed to allocate a new block of
* memory and free the old one if it so desires.
*/
int *new_array = realloc(array, 7 * sizeof(int));
if (new_array == NULL) {
perror("realloc");
exit(1);
}
/* Now array has only 7 items. */
array = new_array;
至于问题的第二部分,您可以增加 array 使其指向您的内存块的中间。然后您可以使用负索引:
array += 3;
int first_int = array[-3];
/* When finished remember to decrement and free. */
free(array - 3);
同样的想法也适用于相反的方向。您可以从 array 中减去以使起始索引大于 0。但请注意:正如 @David Thornley 指出的那样,根据 ISO C 标准,这在技术上是无效的,并且可能不适用于所有平台。
【讨论】:
你不能释放数组的一部分——你只能free()一个你从malloc()得到的指针,当你这样做时,你将释放你要求的所有分配。
就负数或非基于零的索引而言,当您从malloc() 取回指针时,您可以对指针做任何您想做的事情。例如:
int *array = malloc(10 * sizeof(int));
array -= 2;
创建一个具有有效索引 2-11 的数组。对于负指数:
int *array = malloc(10 * sizeof(int));
array += 10;
现在您可以像array[-1]、array[-4] 等一样访问这个数组。
确保不要访问阵列外的内存。这种有趣的事情在 C 程序和 C 程序员中通常是不受欢迎的。
【讨论】:
array -= 2; 是未定义的行为,IIRC,因为它形成了一个既不指向有效内存也不指向某个有效内存末尾的指针值。这通常不是现代计算机的问题,但有些系统(如旧的 Boehm 保守垃圾收集器)会遇到此问题。
array-2 是未定义行为的想法——C 旨在允许在指针寄存器物理上无法保存无效指针的架构上实现。