在C语言中,释放内存块的一半,而不释放另一半

在C语言中,释放内存块的一半,而不释放另一半,c,malloc,free,C,Malloc,Free,如果我已经分配了一个内存块 char *a =(char*)malloc(sizeof(char)*10); 我也是 strcpy( "string of len 5",a); 那么有没有办法释放我剩余的内存块? 在另一种情况下,如果我这样做 strcpy("string of len5", (a+5)); 那么上半场就空了。有没有一种方法可以在不取消分配后半部分的情况下释放前半部分 请不要建议realloc(),因为它会在那里分配新的内存块复制内容并释放以前的内容。(AKAI

如果我已经分配了一个内存块

char *a =(char*)malloc(sizeof(char)*10);   
我也是

strcpy( "string of len 5",a);   
那么有没有办法释放我剩余的内存块?
在另一种情况下,如果我这样做

strcpy("string of len5", (a+5));
那么上半场就空了。有没有一种方法可以在不取消分配后半部分的情况下释放前半部分


请不要建议
realloc()
,因为它会在那里分配新的内存块复制内容并释放以前的内容。(AKAIK)。

不,您无法
释放()动态分配的内存的一半或部分。您需要一次释放所有内容

通过动态内存分配获得内存时,基本上可以得到一个指针。您需要将准确的指针传递到
free()
。传递一个指向
free()
的指针,该指针不是由
malloc()
或family返回的

仅供参考,请参见。
malloc(3)
API不允许这样做,除了
realloc(3)
之外。在常见的实现中,使用realloc进行收缩(通常?)不会触发复制,尤其是在缓冲区很大的情况下


如果您确实希望能够保证不复制,请在POSIX
mmap(2)
/
munmap(2)
之上实现您自己的分配器。您可以取消映射的一部分,而不会影响不在给定地址范围内的页面。

如果不使用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 );
}
另一种方法是简单地将子字符串复制到另一个分配的字符串中。比如说

#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 );
}
当成功地从程序的堆内存空间返回一个逻辑上连续的内存块时,调用malloc,该内存块的大小仅略大于您所请求的大小

这是一个额外的内存,用于存储信息,如分配块的大小,以及到块链中下一个空闲/已用块的链接

当您释放指针时,它使用该地址查找它添加到已分配块的开头(通常)的特殊信息

因此,您不能释放少于使用
malloc
分配的内存。如果您传递不同的地址,它将给出未定义的行为

为此,使用了
realloc

realloc()
不需要复制,良好的实现可以避免不必要的复制。你真的应该相信这一点。(澄清一下:当然是出于性能原因。始终假设实现可能需要一个副本)

#包括
#包括
int main()
{
void*test1=malloc(16);
void*test2=realloc(test1,8);
免费(测试2);
printf(“malloc:%x--realloc:%x\n”,test1,test2);
返回0;
}
示例输出:

malloc:4779c0——realloc:4779c0


你没有办法做到这一点,有必要腾出一半吗?这根本不安全。动态分配的内存必须全部释放。

“请不要建议
realloc()
”–这正是您应该使用的
realloc()
。realloc()
有任何问题吗?如果“不要建议
realloc
”的原因这是因为有多个指针的别名副本浮动,调用realloc可能会使其无效-好吧,不要将指针的多个别名副本放在周围。编程需要纪律。祝你好运。顺便说一句,sizeof(char)是多余的,根据标准,它保证为1。在C语言中,你可以
#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
#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;
}