Reducing the code and examining the sizeof() the member types of Node:
#include <iostream> struct Node { int key; int ltag, rtag; Node* lchild, * rchild; }; int main() { // size of individual types making up the struct: std::cout << "sizeof(int) = " << sizeof(int) << std::endl; std::cout << "sizeof(Node*) = " << sizeof(Node*) << std::endl; // we might expect sizeof(Node) to equal whatever this line prints out: std::cout << "sizeof(int) * 3 + sizeof(Node*) * 2 = " << sizeof(int) * 3 + sizeof(Node*) * 2 << std::endl; // but only this line will tell us for sure std::cout << "sizeof(Node) = " << sizeof(Node) << std::endl; }
As pointed out in the comments, your Node* members, lchild and rchild only get stored as pointers to type Node, they don't store an entire additional Node object each, as you suggested.
Note that the actual size of your objects as returned by sizeof() will vary from platform to platform and possibly even within the same platform. Observe sample output of the above program, running on 64-bit Linux:
sizeof(int) = 4 sizeof(Node*) = 8 sizeof(int) * 3 + sizeof(Node*) * 2 = 28 sizeof(Node) = 32
Note that in this case, even our estimate of the size by summing the size of all the members is incorrect
—the compiler does not have to align data as compactly as possible, and it didn't seem to do so in this case, hence why sizeof(Node) is larger than our estimate of it.
This is different to the size you get reported in your IDE, but neither is incorrect —the compilers are just choosing to arrange the struct data differently in either case.
Another factor that can affect this is if sizeof(int) or sizeof(void*) varies across platforms, which is not unheard of. int is only required to be at least 4 bytes wide, but can be wider, and pointer could be 4 or 8 bytes, depending on the data model used by the system. It looks like your pointers are 4 bytes wide...
sizeof(Node) /*20 in your case*/ = 3 * sizeof (int) /*4 in your case*/+ 2 * sizeof (Node*) /*4 in your case*/ /*+ padding, 0 in your case*/sizeof(Node*)is unrelated tosizeof(Node).<iostream>and you wouldn't cast the result ofmallocexplicitly. In C++ you wouldn't use thetypedef struct Node { /*...*/ } Node;syntax but simplystruct Node { /*...*/ };instead. Also, wouldn't putstructbeforeNodewhen declaring the members. Also, you wouldn't usemallocto create newNodeobjects. You would usenewinstead, or even better, usestd::unique_ptrinstead of raw pointers. Technically it is still valid C++ in this specific case, but especially themallocwill be wrong for non-trivial types.