有这样一个分配器:
template<class T>
class Allocator
{
public:
using value_type = T;
Allocator() noexcept {}
template<class _Other>
Allocator(const Allocator<_Other>&) noexcept
{
//std::cout << typeid(_Other).name() << std::endl;
}
void deallocate(T* const ptr, const size_t count)
{
std::cout << "Allocator::deallocate " << ptr << std::endl;
std::free(ptr);
}
T* allocate(const size_t count)
{
if(count > std::numeric_limits<size_t>::max() / sizeof(T) )
throw std::bad_alloc();
void* ptr = std::malloc(count);
std::cout << "Allocator::allocate " << ptr << std::endl;
return static_cast<T*>(ptr);
}
};
class A
{
public:
A()
{
std::cout << "A() " << this << std::endl;
}
~A()
{
std::cout << "~A() " << this << std::endl;
}
};
这就是我使用它的方式:
int main(int argc, char* argv[])
{
std::vector<A, Allocator<A>> vec;
vec.push_back(A());
return 0;
}
这是程序输出的内容:
Allocator::allocate 00ED7A48
A() 00DCFA33
Allocator::allocate 00ED7DA0
~A() 00DCFA33
~A() 00ED7DA0
Allocator::deallocate 00ED7DA0
Allocator::deallocate 00ED7A48
为什么要调用构造函数A()
?通过cppreference std::malloc
判断不调用构造函数。
我不太明白为什么程序会因消息而崩溃
HEAP_CORRUPTION DETECTED:在 0x00ED7A48 CRT 的 Normal block(#152) 后检测到应用程序在堆缓冲区结束后写入内存;
尝试删除第二个对象时?
因为您正在创建此类型的对象以添加到向量的末尾。
当被调用
std::vector::push_back
时,向量要求它的分配器为一个元素分配内存(实际上,内存是为元素的缓冲区保留的,以避免每次都分配)。为此,它Allocator::allocate
使用参数调用1(один элемент)
。在您的情况下,此函数将为 分配内存один байт
,因为您调用malloc(1)
,但您至少需要 sizeof (T) 个字节。从技术上讲,您的分配器还不适合在向量中使用,因为缺少许多必要的定义(特别是
Allocator::rebind
,Allocator::reallocate
,所有必要类型的别名等),另外,如果malloc
它没有找到足够的内存,则会出现异常永远不会被抛出,因为std::numeric_limits<size_t>::max() / sizeof(T)
它很可能是一个 18 位数字(自己计算有多少演出)。所以这个错误也需要纠正。一般来说,我会同时使用
new
两者delete
,因为运行时差异是难以察觉的,它会在找不到内存时new
调用,现在该函数尝试使用不同的策略来查找内存。而 malloc 不会那样做...new_hendler
new_hendler