如果我已经分配了一个内存块说
strcpy( "string of len 5",a);
我做了
strcpy("string of len5", (a+5));
那么有没有办法将剩下的部分内存块释放出来?free()
然后上半场将是空的。有没有办法realloc()
第一部分没有解除后半部分?
请不要建议{{1}},因为它会在那里分配一大块内存复制内容并释放之前的内容。(AKAIK)。
答案 0 :(得分:6)
不,您无法free()
半或部分动态分配的内存。您需要一次free()
所有。
通过动态内存分配获取内存时,基本上会得到一个指针。您需要将完全指针传递给free()
。将指针free()
传递给malloc()
或家人的/
是undefined behaviour。
仅供参考,请参阅此related answer。
答案 1 :(得分:2)
realloc()
不需要复制,良好的实现可以避免不必要的副本。你真的应该依靠它。 (澄清:出于性能原因,当然。总是假设一个实现可以复制一份)
#include <stdlib.h>
#include <stdio.h>
int main()
{
void *test1 = malloc(16);
void *test2 = realloc(test1, 8);
free(test2);
printf("malloc: %x -- realloc: %x\n", test1, test2);
return 0;
}
示例输出:
malloc:4779c0 - realloc:4779c0
答案 2 :(得分:1)
除了malloc(3)
之外,realloc(3)
API不允许这样做。在常见的实现中,使用realloc(通常是?)缩小不会触发副本,尤其是。不是缓冲区很大。
如果您真的希望能够保证不复制,请在POSIX mmap(2)
/ munmap(2)
之上实现您自己的分配器。您可以取消映射部分映射,而不会影响不在给定地址范围内的页面。
答案 3 :(得分:1)
如果不使用realloc,则无法在C标准的框架中执行任务。使用realloc没有什么复杂的。
这是一个演示程序,展示了如何完成
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HELLO_WORLD "Hello World"
int main( void )
{
char *s;
size_t n = sizeof( HELLO_WORLD );
s = malloc( n );
strcpy( s, HELLO_WORLD );
puts( s );
memmove( s, s + 6, n - 6 );
puts( s );
char *t = realloc( s, n - 6 );
if ( t ) s = t;
puts( s );
free( s );
}
程序输出
Hello World
World
World
另一种方法是简单地复制另一个分配字符串中的子字符串。例如
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define HELLO_WORLD "Hello World"
int main( void )
{
char *s;
size_t n = sizeof( HELLO_WORLD );
s = malloc( n );
strcpy( s, HELLO_WORLD );
puts( s );
do
{
char *t = malloc( n - 6 );
if ( t )
{
strcpy( t, s + 6 );
free( s );
s = t;
}
} while( 0 );
puts( s );
free( s );
}
程序输出
Hello World
World
答案 4 :(得分:0)
当成功从程序的HEAP内存空间返回逻辑上连续的内存块时,调用malloc只比你请求的内容多一点。
这个额外的内存用于存储诸如分配块大小之类的信息,以及链接到块链中下一个空闲/已使用块的链接。
当你释放指针时,它会使用该地址来查找它添加到已分配块的开头(通常)的特殊信息。
因此,你不能释放内存少于你使用malloc
分配的内存。如果你传递不同的地址,它将给出未定义的行为。
为此目的,使用了realloc
。
答案 5 :(得分:0)
你无法做到这一点,有没有必要释放一半?它根本不安全。动态分配的内存必须全部免费。