从mremap分段错误中释放内存

时间:2018-01-26 21:43:06

标签: c mmap

释放已通过mremap(2)更改的内存的规则是什么?实验表明,如果传递给mremap()的地址与返回的地址相同,那么free()将起作用。但是如果返回的地址不同,free()将产生分段错误。例如,

#include <stdio.h>
#include <stdlib.h>

#include <malloc.h>

#define __USE_GNU
#include <sys/mman.h>

#define ALLOC_SIZE (1024 * 1024)

int
main(int argc, char *argv[])
{
        void *m = NULL, *tmp;
        size_t size = 4 * ALLOC_SIZE;

        m = memalign(4096, size);
        if (m == NULL)
                return EXIT_FAILURE;

        tmp = mremap(m, size, size + ALLOC_SIZE, MREMAP_MAYMOVE);

        if (tmp == MAP_FAILED) {
                printf("mremap(%p, %zu, %zu, MREMAP_MAYMOVE) failed\n",
                                m, size, size+ALLOC_SIZE);
        } else {
                if (tmp != m) {
                        printf("Memory moved from %p to %p\n", m, tmp);
                        m = tmp;
                }

                size += ALLOC_SIZE;
        }

        printf("Freeing %zu bytes from %p\n", size, m);
        free(m);

        return EXIT_SUCCESS;
}
除非

,否则

将是段错误

  • MREMAP_MAYMOVE已删除
  • free已更改为munmap

如果答案是不使用memalign系列函数而不使用mmap匿名内存,您是否可以指向手册页或类似内容,说明情况属实?

1 个答案:

答案 0 :(得分:2)

从免费的手册页(man 3 free):

  

free()函数释放ptr指向的内存空间,该内存空间必须由之前调用malloc(),calloc()或realloc()返回。否则,或者如果之前已经调用了free(ptr),则会发生未定义的行为。

基本上使用未由malloc系列分配的free on memory是未定义的。由于您使用mremap作为分配内存的最后一个函数,因此它不是malloc分配的内存。

你必须在mremap之后使用munmap。此外,您不应该将malloc系列与mmap系列混合使用。这只是灾难的一种方法。