假设我有一个分配用于保存 4096 字节的指针。 如何在 C 中释放最后 1024 个字节? 那么在 C++ 中呢? 相反,如果我想释放 first 1024 字节并保留其余部分(两种语言)怎么办? 从中间释放怎么样(在我看来,这需要将其分成两个指针,在释放区域之前和之后)。
不要尝试和事后猜测内存管理。它通常比你聪明;-)
您唯一能实现的就是第一个场景“释放”最后 1K
char * foo = malloc(4096);
foo = realloc(foo, 4096-1024);
但是,即使在这种情况下,也不能保证“foo”不会改变。您的整个 4K 可能会被释放,并且 realloc() 可能会将您的内存移动到其他地方,从而使您可能持有的任何指向它的指针无效。
这对于 C 和 C++ 都有效 - 然而,在 C++ 中使用 malloc() 是一种不好的代码味道,大多数人会期望您使用 new() 来分配存储。并且用 new() 分配的内存不能被 realloc()ed - 或者至少不能以任何可移植的方式。 STL 向量在 C++ 中是一种更好的方法
如果您有
n
字节的 malloc
内存,您可以 realloc
m
字节(其中 m
< n
),从而丢弃最后的 n-m
字节。
要从头开始删除,您可以
malloc
一个新的、更小的缓冲区和 memcpy
所需的字节,然后 free
原始的。
后一个选项也可以使用 C++
new
和 delete
来实现。它还可以模拟第一个realloc
案例。
您没有“分配用于保存 4096 字节的指针”,您有一个指向已分配的 4096 字节块的指针。
如果您的块分配有
malloc()
,则 realloc()
将允许您减少或增加块的大小。不过,块的起始地址不一定保持不变。
您无法更改
malloc
d内存块的起始地址,这确实是您的第二个场景所要求的。也没有办法分割一个 malloc
'd 块。
这是
malloc
/calloc
/realloc
/free
API 的限制——实现可能依赖于这些限制(例如,在起始地址之前保留有关分配的簿记信息,这将导致使移动起始地址变得困难。)
现在,
malloc
并不是唯一的分配器——您的平台或库可能提供其他分配器,或者您可以编写自己的分配器(通过malloc
、mmap
、VirtualAlloc
从系统获取内存)或其他一些机制),然后以您想要的任何方式将其分发给您的程序。
对于 C++,如果您使用
std::malloc
分配内存,则上述信息适用。如果您使用 new
和 delete
,则您正在为对象分配存储并构造对象,因此更改已分配块的大小没有意义 - C++ 中的对象是固定大小的。
您可以使用 realloc() 使其更短。我认为其余的都是不可能的。
您可以使用 realloc() 来明显缩短内存。请注意,对于某些实现,此类调用实际上不会执行任何操作。您不能释放块的第一位并保留最后一位。
如果您发现自己需要这种功能,您应该考虑使用更复杂的数据结构。数组并不是所有编程问题的正确答案。
http://en.wikipedia.org/wiki/New_(C%2B%2B)
总结:与C的realloc相比,它 无法直接重新分配 用new[]分配的内存。延长 或减小块的大小,一 必须分配一个新的足够的块 大小,复制旧内存,以及 删除旧块。 C++ 标准 库提供了一个动态数组 可以延长或减少其 std::向量模板。