auch wenn auf keine memebervariable zugegriffen wurde bzw die funktion nicht statisch war, sollte das trotzdem nicht gehn..
Wer sagt das? :shock:
Nehmen wir mal folgenden Code:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
struct foo
{
int x;
void bar()
{
printf( "foobar 0x%08x", this );
}
};
int main()
{
foo* p = 0;
p->bar();
}
|
Möglicherweise gibt läuft der Code fehlerlos durch und das Programm gibt die Ausgabe "foobar 0x00000000" aus.
Wieso? Sehen wir uns mal den relevanten Assemblercode zu dem Programm an:
|
C-/C++-Quelltext
|
1
2
3
|
mov dword ptr [p], 0 // foo* p = 0
mov ecx, dword ptr [p] // funktionsaufruf für p
call 12345h // foo::bar() aufrufen
|
Der Aufruf funktioniert, da die Funktionsadresse der Methode bekannt ist. Da jedes Objekt die selbe Methode verwendet, der Aufruf also nicht von einer korrekt erzeugten Instanz abhängig ist, kann die Methode auch ohne diese aufgerufen werden.
Weiter gehts in der Methode
foo::bar().
|
C-/C++-Quelltext
|
1
2
3
4
5
6
|
//...
mov eax, dword ptr [this]
push eax // ellipsisparameter von printf
push offset string "foobar 0x%08x" // strfmt parameter von printf
call dword ptr [printf] // printf aufrufen
// ...
|
Auch hier wird das Objekt selbst nicht benötigt. Also theoretisch auch kein Grund das Programm abzuwürgen.
Ändert man nun die Funktion
foo::bar() etwas um
|
C-/C++-Quelltext
|
1
2
3
4
|
void bar()
{
x = 100;
}
|
sähe die Sache wieder etwas anders aus:
|
C-/C++-Quelltext
|
1
2
3
4
|
//...
mov eax, dwprd ptr [this]
mov dword ptr [eax], 64h // oops, dereferenzieren vom 0-Zeiger :)))
//...
|
Hier knallts dann weil versucht wird in einen ungültigen Speicherbreich zu schreiben.