为何该vector构造函数抛出std::bad_alloc异常?构造函数是否存在歧义?
咱们一步步拆解你的问题,先搞清楚异常触发的原因,再聊构造函数的歧义疑问。
一、触发std::bad_alloc的核心原因
问题出在这行初始化vector的代码里:
vector<int> v = vector<int>(start + 1, start - 13);
这里的start是unsigned char*类型,而无符号类型的减法不会产生负数,只会发生下溢(wrap around)。
举个实际场景的例子:假设start指向数组a的首地址(比如地址值为0x7ffeefbff5e0),当你计算start - 13时,因为是无符号指针,这个减法会绕回成一个极大的地址值(如果首地址本身很小,甚至会变成接近内存地址上限的数值)。此时start +1是靠近数组首地址的小地址,而start -13是数值上远大于start+1的地址。
vector的双迭代器构造函数(template <class InputIterator> vector(InputIterator first, InputIterator last);)默认认为first到last是正向有效范围——也就是last在first的后方(对于指针这种随机访问迭代器,就是last >= first)。它会计算两个迭代器的距离:last - first,这个距离在你的场景下会是一个超级大的数值(比如接近4GB的大小)。
当vector尝试分配这么多int元素的内存时,系统完全没有足够的空间,自然就触发了std::bad_alloc异常。
二、vector构造函数是否存在歧义?
答案是:不存在歧义。
vector的常用构造函数里,容易和双迭代器版本混淆的是vector(size_type n, const T& val);(创建包含n个val元素的vector)。但你的两个参数都是unsigned char*类型,属于指针(输入迭代器的一种),编译器会明确匹配到双输入迭代器的构造函数模板,而不会匹配到size_type+初始值的版本——因为unsigned char*无法隐式转换为size_type(通常是size_t,无符号整数类型)。
编译器能清晰区分这两个构造函数的参数类型,所以不存在歧义问题。
快速修复提示
如果你本来的意图是用指针指向的内存范围初始化vector,要保证两个迭代器的顺序正确:first指向范围起始,last指向范围末尾的下一个位置,同时确保指针指向的内存是有效的。比如针对你的数组,正确的范围可以是(注意类型转换的安全性):
vector<int> v(reinterpret_cast<int*>(a), reinterpret_cast<int*>(a + 20));
内容的提问来源于stack exchange,提问作者Sichen Xu

