gpt4 book ai didi

c++ - 为什么 std::string 分配两次?

转载 作者:太空狗 更新时间:2023-10-29 21:21:46 24 4
gpt4 key购买 nike

我为 std::stringstd::vector 编写了一个自定义分配器,如下所示:

#include <cstdint>
#include <iterator>
#include <iostream>

template <typename T>
struct PSAllocator
{
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;

template<typename U>
struct rebind {typedef PSAllocator<U> other;};

PSAllocator() throw() {};
PSAllocator(const PSAllocator& other) throw() {};

template<typename U>
PSAllocator(const PSAllocator<U>& other) throw() {};

template<typename U>
PSAllocator& operator = (const PSAllocator<U>& other) { return *this; }
PSAllocator<T>& operator = (const PSAllocator& other) { return *this; }
~PSAllocator() {}


pointer allocate(size_type n, const void* hint = 0)
{
std::int32_t* data_ptr = reinterpret_cast<std::int32_t*>(::operator new(n * sizeof(value_type)));
std::cout<<"Allocated: "<<&data_ptr[0]<<" of size: "<<n<<"\n";
return reinterpret_cast<pointer>(&data_ptr[0]);
}

void deallocate(T* ptr, size_type n)
{
std::int32_t* data_ptr = reinterpret_cast<std::int32_t*>(ptr);
std::cout<<"De-Allocated: "<<&data_ptr[0]<<" of size: "<<n<<"\n";
::operator delete(reinterpret_cast<T*>(&data_ptr[0]));
}
};

然后我运行了以下测试用例:

int main()
{
typedef std::basic_string<char, std::char_traits<char>, PSAllocator<char>> cstring;

cstring* str = new cstring();
str->resize(1);
delete str;

std::cout<<"\n\n\n\n";

typedef std::vector<char, PSAllocator<char>> cvector;

cvector* cv = new cvector();
cv->resize(1);
delete cv;
}

不管出于什么奇怪的原因,它继续打印:

Allocated: 0x3560a0 of size: 25
Allocated: 0x3560d0 of size: 26
De-Allocated: 0x3560a0 of size: 25
De-Allocated: 0x3560d0 of size: 26




Allocated: 0x351890 of size: 1
De-Allocated: 0x351890 of size: 1

那么为什么它为 std::string 分配两次以及更多的字节?

我在 Windows 8 上使用 g++ 4.8.1 x64 sjlj 来自:http://sourceforge.net/projects/mingwbuilds/ .

最佳答案

我无法重现双重分配,因为显然我的 libstdc++ 根本没有为空字符串分配任何东西。然而,调整大小确实分配了 26 个字节,gdb 帮助我识别 how they are composed :

size_type __size = (__capacity + 1) * sizeof(_CharT) + sizeof(_Rep);
( 1 + 1) * 1 + 24

所以内存主要用于这个_Rep表示,它又由以下数据成员组成:

size_type    _M_length;   // 8 bytes
size_type _M_capacity; // 8 bytes
_Atomic_word _M_refcount; // 4 bytes

我猜最后四个字节只是为了对齐,但我可能遗漏了一些数据元素。

我想这个 _Rep 结构被分配在堆上的主要原因是它可以在字符串实例之间共享,也许还可以避免空字符串,因为缺少我系统上的第一个分配建议。

要找出为什么您的实现不使用此空字符串优化,请查看 the default constructor .它的实现似乎取决于 _GLIBCXX_FULLY_DYNAMIC_STRING 的值,这在您的设置中显然是非零的。我不建议直接更改该设置,因为它以下划线开头,因此被认为是私有(private)的。但是您可能会发现一些公共(public)设置会影响此值。

关于c++ - 为什么 std::string 分配两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21979330/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com