Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 4.0

...

Code Block
bgColor#FFCCCC
langcpp
class Base {
public:
	virtual void func(void) {
		cout << "Base" << endl;
	}
};

class Derived : public Base {
public:
	int i;
	Derived() { i = 0; }

	void func(void) {
		cout << "Derived " << ++i << endl;
	}
};

void walk(class Base *bar, int count) {
	for (int i = 0; i < count; i++) {
		bar[i].func();
	}
}

int main(void) {
	Base dis[3];
	Derived dat[3];

	walk(dis, 3);
	walk(dat, 3); // crashes
}

Wiki MarkupIn the last call to {{walk()}}, {{dat\[\]}} is treated as a {{Base\[\]}} and the subscripting no longer works correctly when {{sizeof(Derived) \ != sizeof(Base)}}. This is because {{walk()}} incorrectly believes that the size of each element in {{bar\[\]}} is {{sizeof(Base)}}. To locate the second element in the array (located at {{bar\[1\]}}), {{walk()}} adds the {{sizeof(Base)}} to the address {{bar}}. Assuming the derived object is larger (which is often the case), the resulting pointer refers to a point within the first element and not to the start of the second element located at {{bar + sizeof(Derived)}}.

Compliant Solution 1

Instead of having an array of objects, an array of pointers solves the problem of the objects being of different sizes. With the Base and Derived classes as in the Non-Compliant Code Example, we can define the walk and main methods as follows.

...

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ARR39-CPP

high

likely

high

P9

L2

Bibliography

Wiki Markup\[[Sutter 04|AA. Bibliography#Sutter 04]\] Item 100: Don't treat arrays polymorphically.unmigrated-wiki-markup

\[[Meyers 96|AA. Bibliography#Meyers 96]\] Item 3: Never treat arrays polymorphically.unmigrated-wiki-markup

\[[Lockheed Martin 05|AA. Bibliography#Lockheed Martin 05]\] AV Rule 96 Arrays shall not be treated polymorphically.unmigrated-wiki-markup

\[[Stroustrup 06|AA. Bibliography#Stroustrup 06]\] What's wrong with arrays?

...

ARR37-CPP. Do not add or subtract an integer to a pointer to a non-array object      06. Arrays and the STL (ARR)      ARR40-CPP. Use a valid ordering rule