-
Strage memory behavior
Any one has any idea why this code if causing glibc errors?
It seems that for some reason casting the buffer to something and then using it,
would mess up with the delete comming up later. If I change that from dynamic
allocation to simple static allocation (just char a[sizeof(s)]) and remove the delete
at the end, everything is fine.
Code:
class A {
public:
A(){}
~A() { std::cout << "I'm dying" << std::endl; }
};
struct s {
A ty;
int a;
float b;
bool c;
};
int main() {
char *a = new char(sizeof(s));
//char a[sizeof(s)];
s *obj = (s*)a;
obj->ty = A();
obj->a = 5;
obj->b = 6;
obj->c = true;
for (int i=0;i<sizeof(s);i++) {
std::cout << "a[" << i << "]=" << *a++ << std::endl;
}
delete a;
return 0;
}
-
Code:
> for (int i=0;i<sizeof(s);i++) {
> std::cout << "a[" << i << "]=" << *a++ << std::endl;
You increment a several times, so a no longer points the the beginning of its allocated memory.
Then you try to delete a, but it's been incremented above. By the way, this should be:
-
> char *a = new char(sizeof(s));
This allocates a single character with an initial value of sizeof(s). What you want is
char *a = new char[sizeof(s)];
And that's still undefined behaviour, due to reinterpretation cast. There might be some platforms out there that happily give you an alignment error, causing your application to crash. Note: while the block of memory allocated by the underlying operator new[]() is guaranteed to be suitably aligned for any object type, there is no such guarantee on the pointer return by new[] itself.
It's also undefined behaviour because you're dereferencing a pointer to an uninitialized non-POD type. (Class A has a destructor, thus it's non-POD. Struct s contains an A, thus it's non-POD.)
If you want raw memory, call operator new() directly. Don't allocate char arrays with new[] unless you actually want char arrays.