What happens to class members when malloc is used instead of new?
I'm studying for a final exam and I stumbled upon a curious question that was part of the exam our teacher gave last year to some poor souls. The question goes something like this:
Is the following program correct, or not? If it is, write down what the program outputs. If it's not, write down why.
The program:
#include<iostream.h>
class cls
{ int x;
public: cls() { x=23; }
int get_x(){ return x; } };
int main()
{ cls *p1, *p2;
p1=new cls;
p2=(cls*)malloc(sizeof(cls));
int x=p1->get_x()+p2->get_x();
cout<<x;
开发者_JAVA技巧 return 0;
}
My first instinct was to answer with "the program is not correct, as new
should be used instead of malloc
". However, after compiling the program and seeing it output 23
I realize that that answer might not be correct.
The problem is that I was expecting p2->get_x()
to return some arbitrary number (whatever happened to be in that spot of the memory when malloc
was called). However, it returned 0. I'm not sure whether this is a coincidence or if class members are initialized with 0 when it is malloc
-ed.
- Is this behavior (
p2->x
being 0 aftermalloc
) the default? Should I have expected this? - What would your answer to my teacher's question be? (besides forgetting to
#include <stdlib.h>
formalloc
:P)
- Is this behavior (p2->x being 0 after malloc) the default? Should I have expected this?
No, p2->x can be anything after the call to malloc. It just happens to be 0 in your test environment.
- What would your answer to my teacher's question be? (besides forgetting to #include for malloc :P)
What everyone has told you, new combines the call to get memory from the freestore with a call to the object's constructor. Malloc only does half of that.
Fixing it: While the sample program is wrong. It isn't always wrong to use "malloc" with classes. It is perfectly valid in a shared memory situation you just have to add an in-place call to new:
p2=(cls*)malloc(sizeof(cls));
new(p2) cls;
new calls the constructor, malloc will not. So your object will be in an unknown state.
The actual behaviour is unknown, because new
acts pretty the same like malloc
+ constructor
call.
In your code, the second part is missing, hence, it could work in one case, it could not, but you can't say exactly.
Why can't 0 be an arbitrary number too? Are you running in Debug mode? What compiler?
VC++ pre-fills newly allocated memory with a string of 0xCC byte values (in debug mode of-course) so you would not have obtained a zero for an answer if you were using it.
Malloc makes no guarantuee to zero out the memory it allocated and the result of the programm is undefined.
Otherwise there are many other things that keep this program from being correct C++. cout
is in namespace std
, malloc
needs to included through#include <cstdlib>
and iostream.h isn't standard compliant either.
精彩评论