有没有办法查询 realloc 会做什么,或者阻止它复制 Windows 和 Linux 上的所有内存?
Is there a way to either query what would realloc do, or prevent it from copying all memory on Windows and Linux?
我正在使用 C++ 实现类似于 std::vector
的容器。它有一个具有相关容量(为该容器保留的内存)和大小(容器的实际大小)的缓冲区。
当用户添加元素,尺寸需要超过容量时,我用realloc
作为新的容量。
容器有一个 reserve
函数,可以设置容量,以防用户事先知道并且不想在用数据填充容器时冒险分配内存。
因此,在大小较小(比如零)而容量较大(比如 1MB)的情况下,可能存在不变量。那如果用户调用reserve(even_bigger_capacity)
,我该怎么办?
我可以直接调用 realloc
,但是如果 realloc
最终分配了一个新的内存块,它会将 1MB 的无用字节复制到其中。
我可以有一个常量:WASTEFUL_COPY_BYTES
并检查 capacity - size > WASTEFUL_COPY_BYTES
,然后手动调用 malloc
和 memcpy
并仅复制需要的内容,以防万一,并且如果差异很小,只调用 realloc
,但在这种情况下,我错过了使用 realloc
的机会,它 会 return 相同的地址.
基本上我需要像 bool try_realloc(void *old_addr, size_t new_size)
这样的东西,如果 realloc
会 return 相同的地址,它会 return true,但不会尝试分配新块并且复制东西。
...或类似 void* part_realloc(void* old_addr, size_t new_size, size_t relevant_size)
的东西,如果它最终分配一个字节,它只会将 relevant_size
字节复制到新块中。
我确定有特定于平台的方法可以实现这两个功能,所以我的问题是:是否有一个具有此类功能的库可以在主要平台上运行,或者如果没有,我将如何实现至少 Windows 和 Linux?
是这样的
所以,在 Windows 上,_expand
正是我所需要的。
在 Linux,事情看起来并不那么简单。我需要深入研究 glibc。也许 malloc_usable_size
会有所帮助。
编辑:不是(好吧不是很多。它 returns 比分配大小多了太少的字节)。似乎没有办法用 glibc 的 public 接口来实现这个。唯一的办法就是翻看glibc的代码,复制数据结构,使用返回内存块之前的chunk,这是一个Bad Idea™
除非有人在此期间提供更好的答案,否则我将在此处报告进一步的发现
我正在使用 C++ 实现类似于 std::vector
的容器。它有一个具有相关容量(为该容器保留的内存)和大小(容器的实际大小)的缓冲区。
当用户添加元素,尺寸需要超过容量时,我用realloc
作为新的容量。
容器有一个 reserve
函数,可以设置容量,以防用户事先知道并且不想在用数据填充容器时冒险分配内存。
因此,在大小较小(比如零)而容量较大(比如 1MB)的情况下,可能存在不变量。那如果用户调用reserve(even_bigger_capacity)
,我该怎么办?
我可以直接调用 realloc
,但是如果 realloc
最终分配了一个新的内存块,它会将 1MB 的无用字节复制到其中。
我可以有一个常量:WASTEFUL_COPY_BYTES
并检查 capacity - size > WASTEFUL_COPY_BYTES
,然后手动调用 malloc
和 memcpy
并仅复制需要的内容,以防万一,并且如果差异很小,只调用 realloc
,但在这种情况下,我错过了使用 realloc
的机会,它 会 return 相同的地址.
基本上我需要像 bool try_realloc(void *old_addr, size_t new_size)
这样的东西,如果 realloc
会 return 相同的地址,它会 return true,但不会尝试分配新块并且复制东西。
...或类似 void* part_realloc(void* old_addr, size_t new_size, size_t relevant_size)
的东西,如果它最终分配一个字节,它只会将 relevant_size
字节复制到新块中。
我确定有特定于平台的方法可以实现这两个功能,所以我的问题是:是否有一个具有此类功能的库可以在主要平台上运行,或者如果没有,我将如何实现至少 Windows 和 Linux?
是这样的所以,在 Windows 上,_expand
正是我所需要的。
在 Linux,事情看起来并不那么简单。我需要深入研究 glibc。也许 malloc_usable_size
会有所帮助。
编辑:不是(好吧不是很多。它 returns 比分配大小多了太少的字节)。似乎没有办法用 glibc 的 public 接口来实现这个。唯一的办法就是翻看glibc的代码,复制数据结构,使用返回内存块之前的chunk,这是一个Bad Idea™
除非有人在此期间提供更好的答案,否则我将在此处报告进一步的发现