C++检查未初始化的迭代器

C++ checking uninitialized iterators

本文关键字:迭代器 初始化 检查 C++      更新时间:2023-10-16

我浪费了大量的时间,因为我忘记初始化迭代器,然后尝试访问它们应该指向的数据。发生此类错误的唯一标记是运行时的分段错误。下面是一个示例:

vector<Foo> V;
//Uninitialized pointer:
vector<Foo>::iterator it;
//....loads of code later, attempt to access pointer that points to nothing
(*it);
//Segmentation fault!

是否有标准技术可以在编译时自动执行此类检查?

在编译时?不。

我可以想到几个运行时助手。首先是使用boost::optional。第二种是设置可用于初始化迭代器的哨兵向量。

static vector<Foo> null_vector;
vector<Foo>::iterator it = null_vector.begin();
...
if (it == null_vector.begin())

在 C++14 中,比较值初始化迭代器是可以接受的。(2013-04 通过)

所以这是真的:

vector<int>::iterator i1{};
vector<int>::iterator i2{};
assert(i1 == i2);

但这仍然无效:

vector<int>::iterator i1;
vector<int>::iterator i2;
assert(i1 == i2);

不过,我不确定哪些编译器支持此功能。

我在实际代码中使用了一些技术。 没有一个正是你要找的。

首先,作为一种编程实践,我通常会在需要它的位置附近实例化一个变量,并在我可以初始化它的时候实例化它。 我从不实例化未初始化的变量。

有时不可能在一个位置实例化和初始化。 在这些情况下,我将使用类似 Boost 的 optional ,在我需要使用它的地方,我将检查是否已设置optional

我经常发现,当无法在一个地方实例化和初始化时,那是因为某些函数的设计笨拙而笨拙,或者它试图做太多。 尝试将这些职责分解为多个函数,您可能会发现最初的问题 - 无法在一个位置初始化和实例化 - 消失并产生更干净的代码。