【问题标题】:Why dont i have to free memory from the heap when reallocating?为什么我在重新分配时不必从堆中释放内存?
【发布时间】:2016-12-12 07:43:54
【问题描述】:

所以我有这个代码:

/* Dynamic Array Reader */

/* Parameters:
 * n: Number of values to be read
 * 
 * Returns: pointer to the dynamically allocated array
 */
int *dyn_reader(unsigned int n) {
    int* array = malloc(n * sizeof (int));
    if (!array)
        return NULL;
    else {
        unsigned int num_read = 0;
        printf("Enter %u integers so they can be put into this array\n", n);
        while (num_read < n) {
            num_read += scanf("%d", array + num_read);
        }
    }
    return array;
}

/* Add to array */

/* Parameters:
 * arr: Existing array of integers
 * num: number of integers in the array before the call
 * newval: new value to be added
 * 
 * Returns: pointer to the allocated array
 */
int *add_to_array(int *arr, unsigned int num, int newval) {
    int* newarray = realloc(arr, (num+1) * sizeof (int)); //allocate one more space
    if (newarray == NULL) //Return original array if failed to allocate
        return arr;

    //free(arr); //free old array -- this throws an error when i try and free up the old array
    newarray[num] = newval;
    return newarray;
}

int main()
{
    /* testing exercise. Feel free to modify */
    int *array = dyn_reader(5);

    array = add_to_array(array, 5, 10);
    array = add_to_array(array, 6, 100);
    array = add_to_array(array, 6, 1000);

    return 0;
}

如您所见,主函数调用 dyn_reader 分配足够的内存以允许数组中有 n 个元素。它从用户那里读取整数并返回数组。

然后主函数调用 add_to_array 重新分配足够的内存以在数组中添加一个添加元素。如果不能,则返回原始数组。如果内存重新分配有效,我将 newval 添加到数组的末尾。在这种情况下,我使用一个新指针来存储新重新分配的数组的位置。当我尝试释放旧数组 (free(arr);) 时,怎么会出错。那个指针不是仍然指向堆上的内存,我不应该释放它吗?

【问题讨论】:

  • Realloc 如果它移动了内存以便能够扩展它,则在成功时释放旧分配。
  • realloc 将分配新的内存量,如果成功,将复制原始内存块,然后释放原始块,最后返回指向新内存块的指针。如果不成功,则返回 NULL,但原始内存保持不变。
  • 如果 realloc 设法扩展您的分配而不移动到不同的地址,那么 realloc 可以为您提供与 return 相同的指针,因此通过 free(arr) 您实际上会释放新重新分配的内存。
  • 在指向内存的指针上调用 free,因为该指针可能指向垃圾,所以已经重新分配是未定义的行为。
  • 因为realloc释放了它,你不能释放它两次。

标签: c realloc


【解决方案1】:

不,如果 realloc 移动到一个新的内存区域,那么它会为您执行“free()”(因此请确保您没有任何其他指针指向该数组!)。 C 标准说(http://pubs.opengroup.org/onlinepubs/9699919799/functions/realloc.html):

The realloc() function shall deallocate the old object pointed to by ptr

Linux 手册页(https://linux.die.net/man/3/realloc)使其更加明确:

 If the area pointed to was moved, a free(ptr) is done.

【讨论】:

  • 从概念上讲,成功的realloc 总是 会释放旧内存并返回具有相同内容的新内存,直到新旧大小的最小值。如果新内存恰好有相同的地址,那就是实现细节。
【解决方案2】:

如果重新分配成功,realloc() 已处理释放与早期指针相关的内存。请注意,指针可能甚至没有改变。

add_to_array() 的另一个问题是调用函数没有任何成功/失败的指示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2013-02-28
    • 2014-04-02
    • 2012-06-28
    • 2012-04-10
    • 2020-04-25
    • 2012-07-27
    相关资源
    最近更新 更多