Main Content

Invalid iterator usage

Mismatched or uninitialized iterators are used in standard algorithm functions and comparison operations

Since R2022a

Description

This checker flags invalid use of iterators. For instance, this checker is raised when:

  • Iterators from mismatched containers are compared to each other.

  • Iterators from mismatched containers are passed to algorithms that expect iterators from the same container.

  • Uninitialized iterators are passed to a standard algorithm function or used in a comparison operation.

  • The end() iterator is passed as the only argument to the vector::erase() method.

Risk

The preceding invalid uses of iterators might result in unexpected behavior.

  • Calling standard algorithms by using mismatched or uninitialized iterators might lead to segmentation faults or undefined behaviors.

  • Because mismatched iterators point to different containers, comparing them fails silently. This behavior might be unexpected and lead to bugs that are difficult to diagnose.

Fix

The preceding invalid use of iterators might indicate typographical errors or logic errors in your code. To fix such defects, use initialized iterators from the same container in standard algorithms and comparison operations.

Examples

expand all

#include <vector>
#include <algorithm>
#include <string>
typedef const std::vector<std::string>  VS;

bool bothHaveKey(VS& v1, VS& v2, const std::string& key)
{
    bool b1 = (std::find(v1.begin(), v2.end(), key) != v1.end());

    bool b2 = (std::find(v2.begin(), v1.end(), key) != v2.end());
    return b1 && b2;
}

In this example, the function std::find expects a first/last pair of iterators from the same container. Because this function is called by using mismatched iterators from different containers v1 and v2, Polyspace® flags these function calls.

Correction — Use Iterators from Same Container

To fix this defect, use iterators that point to the same container when calling std::find.

#include <vector>
#include <algorithm>
#include <string>
typedef const std::vector<std::string> VS;

bool bothHaveKey(VS& v1, VS& v2, const std::string& key)
{
    bool b1 = (std::find(v1.begin(), v1.end(), key) != v1.end());

    bool b2 = (std::find(v2.begin(), v2.end(), key) != v2.end());

    return b1 && b2;
}
#include <vector>
#include <algorithm>
#include <string>
typedef std::vector<std::string>::iterator vs_it;
vs_it first;  
vs_it last;

//first and last are uninitialized
auto findBetween(std::string key)
{
    return std::find(first, last, key); //Noncompliant
}

In this example, the std::find method is called by using uninitialized iterators first and last. Such a call might lead to undefined behaviors. Polyspace flags the call.

Correction — Initialize Iterators Before Use

To fix this defect, initialize the iterators before calling std::find.

#include <vector>
#include <algorithm>
#include <string>

typedef std::vector<std::string>::iterator vs_it;
std::vector<std::string> V;

vs_it first = V.begin();
vs_it last = V.end();

auto findBetween(std::string key)
{
    return std::find(first, last, key); 
}

#include <vector>
#include <algorithm>
#include <string>
typedef std::vector<std::string> VS;

std::string key;

bool foo(VS v1, VS v2)
{
    return std::find(v1.begin(), v1.end(), key) == v2.end();
}

In this example, iterators from the containers v1 and v2 are compared in the function foo. This operation always returns false, which might be unexpected. Polyspace flags the operation.

Correction — Compare Iterators from Same Container

To fix this defect, compare iterators from the same container.

#include <vector>
#include <algorithm>
#include <string>
typedef std::vector<std::string> VS;

std::string key;

bool foo(VS v1, VS v2)
{
    return std::find(v1.begin(), v1.end(), key) == v1.end();
}

Result Information

Group: Programming
Language: C++
Default: Off
Command-Line Syntax: INVALID_ITERATOR_USAGE
Impact: High

Version History

Introduced in R2022a