【发布时间】:2018-04-14 06:12:51
【问题描述】:
我目前正在学习 STL,我遇到了一位老师制作的示例。
template <class T>
struct SpyAllocator : std::allocator<T>
{
typedef T value_type;
SpyAllocator(/*vector args*/) = default;
template<class U>
SpyAllocator(const SpyAllocator<U>& other){}
template<class U>
struct rebind
{
using other = SpyAllocator<U>;
};
T* allocate(std::size_t n)
{
T* p = (T*) new char[sizeof(T) * n];
memorySpy.NotifyAlloc(sizeof(T), n, p);
return p;
};
void deallocate(T* p, std::size_t n)
{
memorySpy.NotifyDealloc(p, n);
delete (char*)p;
}
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
};
template <class T, class U>
bool operator==(const SpyAllocator<T>&, const SpyAllocator<U>&) { return
false; }
template <class T, class U>
bool operator!=(const SpyAllocator<T>&, const SpyAllocator<U>&) { return
false; }
上面是他的分配器实现。
#define String std::basic_string<char, std::char_traits<char>, SpyAllocator<char>>
他将std::basic_string定义为String。
在main.cpp文件中,
int main()
{
DO(String s1 = "Bonjour");
DO(String s2 = " le monde !");
DO(String s3 = s1 + s2);
printf("s3 : %s\n", s3.c_str());
printf("\nDestroy vector\n\n");
return 0;
}
他正在测试 + 运算符和复制构造函数,结果是
String s1 = "Bonjour"
String s2 = " le monde !"
String s3 = s1 + s2
*** Allocate block 1 : 31 elem of 1 bytes
s3 : Bonjour le monde !
Destroy vector
*** Deallocate block 1 : 31 elem of 1 bytes
我的问题是:
1-我统计了String s1和String s2的字符数(包括\0),是19个,但分配了31个。 Allocate block 1 : 31 elem of 1 bytes
这背后的原因是什么?
2- String s1 和 String s2 构造函数似乎没有分配任何内存,但 String s1 和 String s2 仍然有值。
这怎么可能?
感谢您的宝贵时间!
【问题讨论】:
-
#define String ...真是个坏主意。不要为此使用预处理器,使用类型别名:using String = ...(只需将#define String完全更改为using String =即可满足您的所有需求) -
@Justin,谢谢你的评论,我会记住的。但它是由我的一位老师制作的。
-
"...没有分配任何内存..." 查找:“小字符串优化”(小字符串在 std::string 类中直接分配不上通过分配器的堆)。字符串(和向量)有时也会增长所需空间的倍数。 (1.6 和 2 是公倍数)
-
我认为你的老师犯了一个错误,因为他将
new[]与delete配对,即UB。 -
谢谢@Richard Critten!从昨天开始我就一直在研究这个问题,但无法弄清楚背后的原因。你刚刚拯救了我的一天!