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

时间:2015-07-23 10:34:03

标签: c malloc free

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

strcpy( "string of len 5",a);   

我做了

strcpy("string of len5", (a+5));
那么有没有办法将剩下的部分内存块释放出来?
在其他情况下,如果我

free()

然后上半场将是空的。有没有办法realloc()第一部分没有解除后半部分?

请不要建议{{1}},因为它会在那里分配一大块内存复制内容并释放之前的内容。(AKAIK)。

6 个答案:

答案 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)

你无法做到这一点,有没有必要释放一半?它根本不安全。动态分配的内存必须全部免费。