自定义operator delete[]中如何获取总分配内存大小?
如何在类专属operator delete[]中合法获取释放的内存大小?
你遇到的核心问题是:类专属的operator delete[]默认重载只有void*参数,无法直接获取要释放的内存总大小,但C标准(C11及以后)提供了带std::size_t参数的operator delete[]重载形式,编译器会自动传递对应的内存大小,完全不需要额外分配空间存储计数,合法且高效。
解决方案:重载带std::size_t参数的operator delete[]
直接修改X<Id>的operator delete[]实现,添加std::size_t参数,这个参数会由编译器自动传入当前要释放的内存总字节数,和你在operator new[]中拿到的count完全对应。
修改后的完整代码:
#include <cstdio> #include <string> #include <vector> template <int Id> struct X { static inline int held = 0; static void* operator new(std::size_t count) { held += count; return ::operator new(count); } static void* operator new[](std::size_t count) { held += count; return ::operator new[](count); } static void operator delete(void* ptr) { held -= sizeof(X<Id>); ::operator delete(ptr); } // 重载带std::size_t参数的版本,编译器自动传递内存大小 static void operator delete[] (void* ptr, std::size_t count) { held -= count; ::operator delete[] (ptr); } std::string s1; std::vector<int> v1; }; int main() { auto * dx2 = new X<1>[100]; printf("x1d2 %d\n", X<1>::held); delete [] dx2; printf("x1d2 released %d\n", X<1>::held); // 现在输出为0,符合预期 }
关键说明
- 合法性:这个带
std::size_t参数的operator delete[]是C标准明确规定的重载形式,所有符合C11及以后标准的编译器(GCC、Clang、MSVC等)都支持,完全属于标准行为,不存在依赖编译器私有实现的问题。 - 准确性:传入的
count值和operator new[]中接收的总内存字节数完全一致,所以held的加减能准确反映当前堆上的内存持有量,不需要额外处理对象数量或额外开销。 - 兼容性:如果需要兼容旧编译器(C03及以前),这种方法不可用,但目前主流开发环境都已支持C11及以上标准,这个限制基本可以忽略。
内容的提问来源于stack exchange,提问作者calvin
相关产品推荐
相关产品推荐

