:operator delete(void*)是否知道使用::operator new(size_t)分配的内存大小
Does ::operator delete( void * ) know the size of memory allocated with ::operator new( size_t )
上下文:
我正在尝试创建一个自定义分配器,它在某些方面模仿std::allocator
(不是从(,但允许实例化分配器。我的通用容器有构造函数,允许用户指定指向自定义Allocator
对象的指针。当没有指定分配器时,我希望它默认为从抽象Allocator
类派生的单例NewDeleteAllocator
。这简单地封装了全局new
和delete
运算符。这个想法取自Pablo Halpern的《走向更好的分配器模型》。
使用自定义分配器的客户端代码:
// 'foo_container.hpp'
// enclosed in package namespace
template <class T>
class FooContainer
{
private:
// -- Private member properties --
Allocator * allocator;
public:
// -- Constructors --
FooContainer( Allocator * allocator = 0 )
{
this->allocator = !allocator ? (Allocator *)defaultAllocator : allocator;
}
FooContainer( const FooContainer &rhs, Allocator * allocator = 0 )
{
// don't implicitly copy allocator
this->allocator = !allocator ? (Allocator *)defaultAllocator : allocator;
// copying logic goes here
}
}
自定义分配器实现:
// 'allocator.hpp'
// enclosed in package namespace
class Allocator
{
public:
virtual ~Allocator(){ };
virtual void * allocate( size_t bytes ) = 0;
virtual void deallocate( void * ptr ) = 0;
};
class NewDeleteAllocator : public Allocator
{
public:
virtual ~NewDeleteAllocator()
{
}
virtual void * allocate( size_t bytes )
{
return ::operator new( bytes );
}
virtual void deallocate( void * ptr )
{
::operator delete( ptr ); // memory leak?
}
private:
};
//! @todo Only for testing purposes
const Allocator * defaultAllocator = new NewDeleteAllocator();
主要问题:
我知道通过new
进行分配也可能将有关分配的信息与指针一起存储。我意识到用作用域解析运算符::
调用delete
与仅调用delete
并不完全相同,但::delete( ptr )
如何知道ptr
所指向的数据的大小?这是一个安全的操作吗?根据C++标准,根据我的理解,通过void指针进行删除可能会导致未定义的行为。如果这很糟糕,我还能怎么实现呢?
更多详细信息:
我用以下代码做了一些非常粗略的初步测试:
// inside member function of 'FooContainer'
for( size_t i = 0; i < 1000000; i++ )
{
for( size_t j; j = 1; j < 20; j++ )
{
void * ptr = allocator->allocate( j );
allocator->deallocate( ptr );
}
}
我用Xcode的评测工具观察了程序的总内存使用情况。内存使用率保持恒定在较低的值。我知道这不是检查内存泄漏的正确方法。我不知道编译器是否能对此进行优化。我只是在试验这个想法。在我对我的图书馆的架构做出任何承诺之前,我真的很感谢对主要问题的一些意见。整个方法可能一开始就有缺陷。
感谢您的投入。我不想做任何糟糕的假设。
在调用::new
返回的指针上调用::delete
是安全的。对从对::new[]
的调用返回的指针调用::delete[]
是安全的。如果不丢弃x的类型,那么在从对auto x = new {...}
的调用返回的指针上调用delete x
是安全的。如果不丢弃x的类型,那么在从对auto x = new {...}[z]
的调用返回的指针上调用delete[] x
是安全的。混合是UB
"但是::delete(ptr(如何知道ptr的数据大小指向">
C++中动态分配的内存通常是通过堆来实现的。堆最初分配了很大的空间,然后他处理它,让程序处理其中的随机块。堆存储它分配的每个内存块的大小。例如,如果您需要8个字节的内存,堆至少为您保留12个字节,将大小保留在前4个字节中,将数据保留在后8个字节中。然后,它返回一个指向8个字节的指针。因此,在删除过程中,程序通过访问指针-4知道要删除多少。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 只读位置'__result.std::_Rb_tree_const_iterator<_Tp>::operator*<long long int>()'分配错误
- 为什么 std::vector::operator= 过度分配内存
- 我得到"将值分配给结构数组 iin 时与'operator='不匹配C++
- 错误:分配只读位置“arr2.IntArray::operator[](1)”arr2[1]=24;
- 我可以对单个元素数组分配使用“operator delete[]”吗
- g++ 4.9.0允许对位置分配使用operator delete[](void*, size_t)
- :operator delete(void*)是否知道使用::operator new(size_t)分配的内存大小
- 获取使用operator new[]分配的单个元素的大小或元素计数