Reputation:
Here is the code I have:
#include <iostream>
#include <typeinfo.h>
typedef struct A
{
friend class W;
private:
char c;
void *v;
} A;
typedef struct LL
{
friend class W;
private:
int n;
LL *next, *prev;
} LL;
class W
{
private:
void Handle(void *arg1, void *arg2)
{
A *ob1 = reinterpret_cast<A*>(arg1);
ob1->c = 'c';
ob1->v = (void*)0xffffffff;
LL *ob2 = reinterpret_cast<LL*>(arg2);
ob2->n = 0xff;
ob2->next = new LL();
ob2->prev = 0;
}
protected:
void Set()
{
A *ob1 = new A();
LL *ob2 = new LL();
this->Handle(&ob1, &ob2);
}
};
class R : W
{
public:
R(void)
{
this->Set();
}
};
void main(void)
{
R *ob = new R();
}
I'm getting the next result from dump: Run-Time Check Failure #2 - Stack around the variable 'ob2' was corrupted.
'http.exe': Loaded 'C:\Users\root\Documents\Visual Studio 2008\Projects\http\Debug\http.exe'
, Symbols loaded.
'http.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll'
'http.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll'
'http.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll'
'http.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.1_none_bb1f6aa1308c35eb\msvcr90d.dll'
Run-Time Check Failure #2 - Stack around the variable 'ob2' was corrupted.
My quesions are:
- What should I do to solve this problem?
- Why I have got such error, can you describe me, why its was exaclty corrupted?
- And why the Stack is corrupted? not the heap?
Thanks,
Best regards,
Upvotes: 1
Views: 9058
Reputation: 234644
A *ob1 = new A();
LL *ob2 = new LL();
this->Handle(&ob1, &ob2);
ob1
and ob2
are already pointers. By taking the addresses of the variables (of types, respectively, A**
and LL**
), then passing them to Handle
where they are hammered into A*
and LL*
with reinterpret_cast
s and then written to, the code invokes undefined behaviour. In this particular case it appears to be writing to locations near the ob1
and ob2
variables, which are probably on the stack frame of a call to Set
.
If instead of butchering the type system with reinterpret_cast
, the code used it properly, the compiler would have caught the error immediately:
void Handle(A *arg1, LL *arg2)
{
ob1->c = 'c';
ob1->v = (void*)0xffffffff;
ob2->n = 0xff;
ob2->next = new LL();
ob2->prev = 0;
}
// ...
// the compiler would complain about this call making the problem clear
this->Handle(&ob1, &ob2);
It would be even better if the code didn't use so many pointers all over the place, but I'm going to assume this was just a simple piece of code to demonstrate the problem.
Upvotes: 4