...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <iostream> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; void f(const S *SomeSessomeSes, std::size_t Countcount) { for (const S *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) { std::cout << SomeSessomeSes->I>i << std::endl; } } int main() { T Testtest[5]; f(Testtest, 5); } |
This example would still be noncompliant if the for
loop had instead been written to use array subscripting, as in the following:
Code Block |
---|
for (std::size_t i = 0; i < Countcount; ++i) { std::cout << SomeSessomeSes[i].Ii << std::endl; } |
Compliant Solution (Array)
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <iostream> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; void f(const S * const *SomeSessomeSes, std::size_t Countcount) { for (const S * const *Endend = SomeSessomeSes + Countcount; SomeSessomeSes != Endend; ++SomeSessomeSes) { std::cout << (*SomeSessomeSes)->I>i << std::endl; } } int main() { S *Testtest[] = {new T, new T, new T, new T, new T}; f(Testtest, 5); for (auto Vv : Testtest) { delete Vv; } } |
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.
...
Code Block | ||||
---|---|---|---|---|
| ||||
#include <iostream> #include <vector> int GlobIglobI; double GlobDglobD; struct S { int Ii; S() : Ii(GlobIglobI++) {} }; struct T : S { double Dd; T() : S(), Dd(GlobDglobD++) {} }; template <typename Iter> void f(Iter Ii, Iter Ee) { for (; Ii != Ee; ++Ii) { std::cout << (*Ii)->I>i << std::endl; } } int main() { std::vector<S *> Testtest{new T, new T, new T, new T, new T}; f(Testtest.cbegin(), Testtest.cend()); for (auto Vv : Testtest) { delete Vv; } } |
Risk Assessment
Using arrays polymorphically can result in memory corruption, which could lead to an attacker being able to execute arbitrary code.
...