When using C++,
if there is a class:
class MyClass
{
char memory1bye;
int memory4bytes;
int another4bytes;
};
this class uses total of 9 bytes at memory… so if i do something like:
MyClass *t1;
This will give me a usable address for the Class, but will it allocate the 9 bytes? And will it call default constructor?
Or do I need to malloc those 9 bytes to the class?
If then I called something like:
t1 = (MyClass *)new MyClass;
will it be considered memory leak? In other words, what happens to the old address?
As many people have said, the size of
MyClassis implementation-dependent. In this case, because the class has no methods, you’ve basically got a struct so it is possible to make some reasonable guesses as to size. On a normal modern 32-bit machine without any unusual compiler flags, the size of the structure will be 12 bytes; this follows from the fact that fields are aligned to 4-byte boundaries by default on current architectures.On a 64-bit machine it could be even larger, but I’d be a bit surprised if it was bigger than 24 bytes (i.e., 8-byte alignment for each field). I don’t think anything uses anything larger than 8-byte alignment for fields unless explicitly told to, and there’s not much point in using larger alignment values for fields as the memory allocation functions themselves usually have 8-byte alignment. (NB: Don’t count on that being true for your machine!)
The only way to actually know the size of anything is to use
sizeof(MyClass). You hardly ever need to use that in C++, as thenewoperator knows about that for you and allocates the amount of space needed. And as previously noted, remember that sizes of anything (other thanchar) are not portable, even if they don’t actually vary gratuitously.Doing
MyClass *t1;doesn’t allocate anything. It just gives you a place to store the address of an object (specifically, aMyClassinstance). By default, that space points off into la-la land if the variable is in any local scope or in a class or structure definition. If you’re not about to put an address in the variable, it’s probably a good idea to explicitly initialize it toNULLso that it at least points to a definite not-an-object.Your
t1 = (MyClass *)new MyClass;contains an unnecessary cast, sincenewreturns a pointer to an object of that type anyway. Doingt1 = new MyClass;is enough.If
t1was previously pointing to an object and was the only variable pointing to it, you’ll have a memory leak (assuming you’ve not used a garbage collector library; most C++ programs are written without using them). If something else is pointing to the object, then that had better be assuming the responsibility for cleaning it up. If the address isn’t pointing to anything in particular, or it was pointing toNULL, then nothing is leaked.Remember, addresses don’t leak; objects leak.
You can mitigate memory leaks by creating the objects on the stack (with straight
MyClass t1;) and passing them around by reference rather than address; the object will then be deleted automatically when it passes out of scope. The main disadvantage of this comes when you have an object whose lifetime can’t be coupled nicely to a particular scope. That’s when you use pointers (or smart pointers, which hide most of the details at a cost of some restrictions). Really complex code is just better with garbage collection, though that has its own trade-offs (notably including being much more likely to increase memory consumption; this is the core reason why Java is known for being more memory hungry than C++).