c++ - c++ 11: &v[0] 在空的 std::vector v 上
问题描述
如果我有一个有时可能为空的 std::vector v ,是 g++ 纯属运气,我可以用 &v[0] 获得指向这个不存在数据的指针,还是我会得到其他编译器的段错误(我的 g++ 对以下内容很好,并且在实际运行中从未给出过段错误)。
std::vector<int> v = {}; std::cout << (&v[0] == NULL) << std::endl; // true with my g++
谢谢
解决方案
是的,您的代码具有未定义的行为。
v[0]
调用一个返回的函数int&
,并且没有“空引用”,所以&v[0]
一开始就永远不能为 NULL。这就是为什么带有优化的 clang 会打印您的代码0
,并将以下内容优化为return false;
:
bool is_pointer_to_first_null(std::vector<int>& v) {
return &v[0] == nullptr;
}
(哪个clang也警告你)
它还破坏了std::vector<T>::operator[](n)
定义为等效于的合同*(v.begin() + n)
,并且由于v.begin() + 0 == v.begin() == v.end()
对于空向量,这不是可取消引用的迭代器,并且您的标准库实现可以做任何事情。
例如,使用已定义,这将使用 g++_GLIBCXX_DEBUG
打印。Error: attempt to subscript container with out-of-bounds index 0, but container only holds 0 elements.
(https://godbolt.org/z/anran5)
在 gcc 中&v[0] == nullptr
未优化的事实是错过了优化。false
也许&v[0]
已经优化到v.data()
first 并且 this 为非 null 的信息丢失(或出于任何原因不使用)。
如果没有优化,gcc 将很乐意形成空引用,因为引用是作为指针实现的,并且&reference
在汇编中是一个 noop。对于大多数架构上的大多数编译器来说都是如此,因此这不太可能出现段错误。
也许您正在寻找v.empty()
(它仍然可以有一个非空数据指针)、v.data() == nullptr
(当定义时v.data() == &v[0]
),或者v.capacity() == 0
?不过,不应该有充分的理由检查数据指针是否为空。
推荐阅读
- android - 被“libcurl.so”引用时无法定位符号“EVP_MD_CTX_new”
- sql-server - VS 架构比较 - 从权限更新中排除“AS [dbo]”?
- url - 多个应用程序的 IIS 重写和反向代理
- javascript - 尝试向产品管理页面添加新类别时出现 Wordpress JS 错误
- python - 在控制台中打印数据时,熊猫数据框仅显示外列
- python - 如何在熊猫数据框中展平数组
- python - Pandas 使用元组和通配符进行过滤
- asp.net-core - 如何验证 ASP.NET Core DI 中的所有注册类型?
- flutter - 如何在颤动中更改时间选择器的标题文本主题
- php - League\Monga 更新查询示例