字符串到矢量的转换抛出 std::bad_alloc
string to vector conversion throws std::bad_alloc
我在从字符串创建向量时遇到问题。有人可以解释一下下面 4 种情况之间的区别吗?根据 cplusplus.com,出于同样奇怪的原因,我希望Case 1
像Case 2
一样工作,但事实并非如此。
typedef std::vector<uint8_t> uint8vec_t;
std::string keySecret ()
{
return std::string ("SomeSecret");
}
案例1
// throws std::bad_alloc
uint8vec_t vSecret (keySecret ().begin (), keySecret ().end ());
案例2
// results in a vector with strange length
uint8vec_t vSecret (keySecret ().begin (), keySecret ().begin () + keySecret ().length ());
案例3
// throws std::bad_alloc
uint8vec_t vSecret (&keySecret ()[0], &keySecret ()[keySecret ().length ()]);
案例4
// throws std::bad_alloc
uint8vec_t vSecret (&keySecret ()[0], &keySecret ()[0] + keySecret ().length ());
它们都很糟糕,你只是碰巧在第二种情况下得到了看起来像正确的行为。问题是keySecret
每次都返回不同的std::string
对象。您不能对一个调用begin
,对另一个调用end
,并期望它们以任何方式相关。
相反,您应该调用keySecret
一次,创建本地副本,然后在该单个本地对象上调用begin
和end
。
在两次调用 keySecret()
之后,内存中有两个不同的字符串:
...x..x....SomeSecret ..x.x.x...x..x..x.x...SomeSecret ....x.x..x.x..
^ ^ ^ ^
begin1 end1 begin2 end2
然后,您尝试使用任一方法创建向量
vector<char> v(begin1, end2);
或
vector<char> v(begin2, end1);
(取决于哪个字符串恰好在内存中较早,哪个字符串由哪个keySecret()
调用返回)。
第一个将分配end2 - begin1
字节并将"SomeSecret ..x.x.x...x..x..x.x...SomeSecret "
复制到该内存中,两个迭代器之间具有任意数量的字节,包含字符串之间恰好在内存中的任何内容。这是未定义的行为,因为读取超过了为第一个字符串分配的内存的末尾。
第二个将尝试查找负数的距离end1 - begin2
,因此换行到一个非常大的无符号数字,并尝试分配这么多字节失败,引发bad_alloc
异常。
在这两种情况下,对指向不同对象的两个不相关的指针执行指针算术都是未定义的行为,因此理论上任何事情都可能发生。在实践中,结果可以相当合乎逻辑地解释,如上所述(尽管对于第一种情况来说,段错误并不是一个令人惊讶的结果,而不是内容错误的向量)。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- 获取错误:在抛出"std::bad::alloc"的实例后终止调用 what(): std::bad_alloc
- "std::vector"在调整大小时引发"bad allocation"异常
- 成员函数 bad() 的 std::ftsream 用于检查
- 正在使用std::string而不是char*bad
- 在抛出 'std::bad _alloc' 的实例后调用终止 what(): std::bad_alloc 在 c++ 中
- What is Scala for: getline(), std::cin.eof(), std::cin.bad()