realloc()是否释放旧内存(当旧内存可能指向其他内存时)?

时间:2016-08-30 00:03:28

标签: c memory memory-management free realloc

假设我有一个指向结构s1的数组(在堆上)的指针p1,其中每个struct s1也有一个指向另一个struct s2的指针(在堆上)。如果我在p1上调用realloc()来调整它的大小,那么是否会释放预重新分配的数组的结构所保留的旧内存(堆上的s2s)?

我相当肯定这个问题的答案是否定的,因为文档说明if the area pointed to was moved, a free(ptr) is done意味着它只能释放一个级别。那是对的吗?如果是这样,最好的解决方案是手动malloc一个新数组,迭代旧数组,将值复制到新的更大数组,并在结束时释放结构?

3 个答案:

答案 0 :(得分:2)

不,realloc可以免费获得1级,但不能更多。它不会释放结构中的指针。我说它可以免费使用,因为如果阵列可以生长而不会被移动,它就会在同一个地方生长。

你建议的另一种解决方案是realloc在幕后做的事情(假设我们仍然在谈论扩大数组而不是其他一些结构操作),而且通常一个坏主意从标准库中重新实现一个东西,除非你有充分的理由(而且你似乎没有)。

答案 1 :(得分:1)

realloc()仅重新分配您提供的顶级数组。正如评论中提到的EOF,它不知道数组的内容是指针,所以它不能对这些元素做任何事情。

如果您要扩大阵列,则无需对其指向的阵列执行任何操作。它们的内存不受影响,指针将从旧内存复制到realloc()分配的新内存。

如果要缩小数组,则需要确保首先释放超出结果末尾的元素所指向的任何数组,以避免泄漏内存。

答案 2 :(得分:1)

答案肯定是否定的。 Realloc的工作原理如下:

realloc将使用现有指针或分配新指针(如果旧指针无法缩小或扩展)。如果分配了新指针,则会复制旧内存的内容(与新位置一样多)。

在你的情况下,如果realloc缩小了内存块,那么新块中的所有s1指针都是有效的,但s1指针超出了新的内存块会导致内存泄漏,因为s1指针和s2都没有指针被释放了。为了避免内存泄漏,你应该在调用realloc之前释放它们指向的内存。

使用realloc需要注意的另一件事是,如果它返回null,那么旧的内存指针仍然有效,所以你应该保留它的副本,并在失败时重用或释放它。