Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Do not use pointer arithmetic, including array subscripting, on polymorphic objects.

Noncompliant Code Example

In this noncompliant code example, f() accepts an array of S objects as its first parameter. However, main() passes an array of T objects as the first argument to f(), which results in undefined behavior due to the pointer arithmetic used within the for loop.

...

Code Block
for (std::size_t i = 0; i < Count; ++i) {
  std::cout << SomeSes[i].I << std::endl;
}

Compliant Solution (Array)

Instead of having an array of objects, an array of pointers solves the problem of the objects being of different sizes, as in this compliant solution:

...

The elements in the arrays are no longer polymorphic objects (instead, they are pointers to polymorphic objects), and so there is no undefined behavior with the pointer arithmetic.

Compliant Solution (std::vector)

Another approach is to use an STL container instead of an array and have f() accept iterators as parameters, as in this compliant solution. However, since STL containers require homogeneous elements, pointers are still required within the container.

Code Block
bgColor#ccccff
langcpp
#include <iostream>
#include <vector>

int GlobI;
double GlobD;

struct S {
  int I;
  
  S() : I(GlobI++) {}
};

struct T : S {
  double D;
  
  T() : S(), D(GlobD++) {}
};

template <typename Iter>
void f(Iter I, Iter E) {
  for (; I != E; ++I) {
    std::cout << (*I)->I << std::endl;
  }
}

int main() {
  std::vector<S *> Test{new T, new T, new T, new T, new T};
  f(Test.cbegin(), Test.cend());
  for (auto V : Test) {
    delete V;
  }
}

Risk Assessment

Using arrays polymorphically can result in memory corruption, which could lead to an attacker being able to execute arbitrary code.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CTR39-CPP

High

Likely

High

P9

L2

Automated Detection

Tool

Version

Checker

Description

 PRQA QA-C++
Include Page
PRQA QA-C++_V
PRQA QA-C++_V
3072,3073 

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

Bibliography

[ISO/IEC 14882-2014]

5.7, "Additive Operators"
5.2.1, "Subscripting" 

[Stroustrup 06]What's wrong with arrays?
[Meyers 06]Item 3: Never treat arrays polymorphically
[Lockheed Martin 05]AV Rule 96 Arrays shall not be treated polymorphically.
[Sutter 04]Item 100: Don't treat arrays polymorphically

...