第一个问题:
realloc(array, 0)
不等于。_free(array)
标准(C99,§7.20.3.4 ¶1)说:
该realloc
函数释放 所指向的旧对象,ptr
并返回一个指向具有 指定大小的新对象的指针size
。
并且没有给出 a 的“特殊情况” size==0
;所以,你得到一个指向一个大小为零的对象的指针——但它可能仍然是一个对象,并且仍然必须被释放。
有趣的是,我认为realloc
在这种情况下可能会失败,返回NULL
;在这种情况下,在您的代码中,内存泄漏了,因为当realloc
失败时,它不会释放您传递给它的原始内存块(这就是您从不这样做的原因,array = realloc(array, size)
但您总是使用中间变量NULL
按顺序检查以避免内存泄漏)。
实际上,该标准确实size==0
为所有内存分配函数指定了实现定义的行为,而不仅仅是malloc
我记得的那样;因此,行为是实现定义的,如下所述:
更直观地说,在另一个指针上与 to ++“概念上等效”,并且-ingrealloc
一个malloc
0字节的内存块返回一个唯一的指针,不用于存储任何东西(您要求 0 字节),但是仍有待编辑。所以,不,不要那样使用,它可能适用于某些实现(即 Linux),但肯定不能保证。memcpy
free
malloc
NULL
free
realloc
此外,目前尚不清楚您是如何推断出这free
行不通的。我可以想到两种你可能已经确信这一点的方法:
array
它指向的数据的值和值不变;
- 任务管理器中分配的内存
top
//无论什么都没有减少。
对于第一种情况,这是正常的;当你释放一个指针时,它不会神奇地被擦除——你的指针仍然指向它所指向的位置,但该内存不再是你的——它现在回到了 C 运行时,它可能会在未来重新放弃它malloc
. 这就是为什么那个东西被称为“悬空指针”的原因,许多人在free
设置它之后NULL
避免在已经释放的内存空间中再次写入。
至于第二个,分配器通常不会立即将内存归还给操作系统(除非我们谈论的是非常大的块);这个想法是,应用程序可能很快会再次需要这样的内存,并且为当前进程保留该内存可以避免连续的系统调用以从操作系统获取/提供内存。由于用于监视正常使用的内存的系统实用程序只能查看操作系统为进程提供的内容,因此它们没有显示任何内存使用量减少是正常的。
顺便说一句,请记住,如果您char ** array
包含指向用 分配的东西的指针,则malloc
必须free
首先指向它们,否则您会泄漏内存。
第二个问题:
C 字符串是空终止的,即字符串的最后一个字符始终是 a\0
以标记字符串的结尾,同时strlen
为您提供不包括空终止符的字符串长度。因此,如果您不添加,+1
则分配char
的内存比实际存储字符串所需的内存少一。
附录
不起作用我的意思是它确实崩溃了(问题可能在其他地方)但是当我将它更改为 realloc(X, 0) 时它确实起作用了,在删除使用的动态已用内存的意义上
正如手册页所说,
malloc()、calloc()、realloc() 或 free() 中的崩溃几乎总是与堆损坏有关,例如溢出分配的块或释放相同的指针两次。
您的代码中可能还有其他一些错误,但是如果没有看到它,就不可能知道哪里/哪里出了问题。