我不明白为什么这段代码会出错。我用分配器为给定类型的n个元素分配了足够的空间,然后用std::fill用默认构造类型的副本填充空间。
#define TESTED_TYPE std::string
size_t n = 5;
std::allocator<TESTED_TYPE> my_alloc;
TESTED_TYPE *data = my_alloc.allocate(n);
TESTED_TYPE val = TESTED_TYPE();
std::fill(data, data + n, val);
这段代码编译的很好,基本类型如int,char等不会崩溃,但std::string不会。如果我给予std::fill一个非空字符串,代码也不会出现segfault。为什么?
1条答案
按热度按时间mbyulnm01#
您从未调用
std::string
构造函数,因此data
指向的内存是未初始化的垃圾。std::fill
(可能)实现了一个循环,它对传递的范围内的每个元素执行*ptr = value;
。std::string::operator=
必须确保它先前占用的任何内存都被释放,因此它在其内部缓冲区上调用delete[]
。由于该缓冲区只是一个任意地址,因此它经常访问未Map的内存并崩溃。要解决这个问题,还需要对每个新分配的数组元素调用placement new运算符,以便它们的内部状态保持一致并可以安全使用。