Using the sizeof operator on a struct?

P

Peter Koch Larsen

Casper said:
How would one go about summing up the memmory custom tree structures
occupies in memmory?

Example:

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class
};

node* pNode = new node;

Using the sizeof(&pNode) returns 4.

So pointers on your architecture are four bytes.
What I am interested in however, is
to know the entire memmory use of an instance of a struct.
Will I have to implement a recursive getSize() method for each node to
include the size of the two struct pointers, the unsigned int and the
string object?

Nope... sizeof(node) returns the number of bytes required by one node. This
is a compile-time value, of course, telling you nothing about the actual
storage requirement of an initialised node.
Thanks in advance,
Casper

/Peter
 
D

Dave

Casper said:
How would one go about summing up the memmory custom tree structures
occupies in memmory?

Example:

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class
};

node* pNode = new node;

Using the sizeof(&pNode) returns 4. What I am interested in however, is
to know the entire memmory use of an instance of a struct.
Will I have to implement a recursive getSize() method for each node to
include the size of the two struct pointers, the unsigned int and the
string object?

Thanks in advance,
Casper

You need sizeof(node) * number of nodes.

You could get number of nodes by either keeping track of it dynamically as
you add / delete nodes or you could calculate it on-demand with a full
traversal of the tree.

You'll never be able to know the size of the tree at compile time because
it's size is not fixed at compile time (and sizeof is strictly a
compile-time facility).
 
D

Dave

Casper said:
Ah sizeof is only evaluated at compile time, it won't be of much help to
me then. All I really is interested in is monitoring the memmory usage
of my tree as the primary metric to see the effect of optimizations. Is
there no way to keep track of memmory in the program itself?

Casper

There's nothing in *standard* C++ that will give you the size of a process's
memory image (and standard C++ is what this newsgroup deals with). However,
there is probably some API call specific to your platform that will do what
you want. Also, my earlier post suggests something that I think will work
for you...
 
S

Steve

How would one go about summing up the memmory custom tree structures
occupies in memmory?

Example:

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class
};

node* pNode = new node;

Using the sizeof(&pNode) returns 4. What I am interested in however, is
to know the entire memmory use of an instance of a struct.


sizeof(&pNode) == sizeof(node**)
sizeof(pNode) == sizeof(node*)
sizeof(*pNode) == sizeof(node)


Does that help?

Steve.
 
C

Casper

How would one go about summing up the memmory custom tree structures
occupies in memmory?

Example:

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class
};

node* pNode = new node;

Using the sizeof(&pNode) returns 4. What I am interested in however, is
to know the entire memmory use of an instance of a struct.
Will I have to implement a recursive getSize() method for each node to
include the size of the two struct pointers, the unsigned int and the
string object?

Thanks in advance,
Casper
 
C

Casper

Nope... sizeof(node) returns the number of bytes required by one node. This
is a compile-time value, of course, telling you nothing about the actual
storage requirement of an initialised node.

Ah sizeof is only evaluated at compile time, it won't be of much help to
me then. All I really is interested in is monitoring the memmory usage
of my tree as the primary metric to see the effect of optimizations. Is
there no way to keep track of memmory in the program itself?

Casper
 
C

Casper

You need sizeof(node) * number of nodes.

But how does that help me, this gives me only the total memmory of all
node pointers, not including struct member variables - in particular
when one of the members is a reference to a class (string).

Thanks for the feedback though, I will try to hunt for a solution in my
OS API!
Casper
 
S

Siemel Naran

Casper said:
int CalcSizeOf(node* pNode)
{
long size = pNode->folder.GetAllocLength() * sizeof(TCHAR);
size += sizeof(pNode->nChildCount);
//Parent pointer AND ourself, hence x2
size += (2 * sizeof(pNode->parent));
return size;
}

Don't forget the sizeof(pNode->folder) itself. Most non-reference counted
strings contain a pointer to the start of the string, pointer to the end,
and integer reflecting the capacity (what appears to be GetAllocLength in
your string class).

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class
};

Your function calculates a long, but returns an int! Beware losing
precision.

unsigned long CalcSizeOf(node* pNode) {
unsigned long size = sizeof(pNode);
if (pNode) {
size += sizeof(*pNode);
size += pNode->folder.GetAllocLength() * sizeof(TCHAR);
}
return size;
}

And what if your string class is reference counted? Then sizeof(string) is
sizeof a pointer to the representation. For all the distinct
representations you have to count the sizeof the representation, plus the
sizeof the actual char[] array.

I don't think padding is an issue in your case.

Also, do you want CalcSizeOf(node* pNode) to give the memory consumed by a
node along with its children?

Also, if you make a class with a private member node * pNode, and public
functions to attach/delete child nodes to it and change the values of a node
(such as changing the value of folder), you could keep track of the memory
allocation.

And like hidden bank fees, there could be other hidden costs of memory. So
then we'd have to rely on platform dependent APIs :(.
 
C

Casper

sizeof(&pNode) == sizeof(node**)
sizeof(pNode) == sizeof(node*)
sizeof(*pNode) == sizeof(node)


Does that help?

Steve.

What I need is the entire memmory occupied by the pNode incl. its member
data, so sizeof(node) which only yeilds the size of a pointer is not
very interesting. I thought there was a more elegant way, but I've made
a method to calculate it for me. I guess that is the way to go:

int CalcSizeOf(node* pNode)
{
long size = pNode->folder.GetAllocLength() * sizeof(TCHAR);
size += sizeof(pNode->nChildCount);
//Parent pointer AND ourself, hence x2
size += (2 * sizeof(pNode->parent));
return size;
}
 
K

Karl Heinz Buchegger

Casper said:
What I need is the entire memmory occupied by the pNode incl. its member
data, so sizeof(node) which only yeilds the size of a pointer is not
very interesting. I thought there was a more elegant way, but I've made
a method to calculate it for me. I guess that is the way to go:

int CalcSizeOf(node* pNode)
{
long size = pNode->folder.GetAllocLength() * sizeof(TCHAR);
size += sizeof(pNode->nChildCount);
//Parent pointer AND ourself, hence x2
size += (2 * sizeof(pNode->parent));
return size;
}

struct node {
struct node *parent;
unsigned int nChildCount;
string folder; //string class

int Size()
{ return sizeof( node ) + folder.GetAllocLength(); }
};

There is no need to sum up the sizes of the immediate member
variables. sizeof applied to a node structure (in contrast
to applying it on a pointer as you did) will do that for you.
 
C

Casper

Your function calculates a long, but returns an int! Beware losing
precision.
Yes thanks, that is a clearly a mistake!
Also, do you want CalcSizeOf(node* pNode) to give the memory consumed by a
node along with its children?
That's the overall goal, right now I am summing up while building my tree.
Also, if you make a class with a private member node * pNode, and public
functions to attach/delete child nodes to it and change the values of a node
(such as changing the value of folder), you could keep track of the memory
allocation.
Yes this is the true OO way, however in my attempt to minimize memmory
use I do not keep an eye on children at all, but let a node know its
parent and a counter to increment/decrement when I add delete childs.

This way my cleaning up algorithms are a bit complicated but I appear to
save 30% on each node - again with 50.000+ nodes mem use is a critical
requirement for me.

Thanks for your feedback! :)
Casper
 
S

Siemel Naran

Casper said:
Yes this is the true OO way, however in my attempt to minimize memmory
use I do not keep an eye on children at all, but let a node know its
parent and a counter to increment/decrement when I add delete childs.

How is the counter used?

You could always do something like this:

struct Whatever {
string folder;
etc;
#if defined(_DEBUG)
std::list<Whatever *> children;
#endif
};
This way my cleaning up algorithms are a bit complicated but I appear to
save 30% on each node - again with 50.000+ nodes mem use is a critical
requirement for me.

Please explain further. How do you manage to save memory?
 
C

Casper

Well if I wanted to be able to clean from memmory, all nodes in a tree,
I would have to let the root node know its childs, these childs know
their childs etc. so a simple DFS destructor calling could clean up.

However, this would require an array, linket list or whatever to point
to these childs of every node. Eg. "C:\" would have to point to "Program
files", "WinNT" etc.

However, since I am building a directory tree primarily to allow file
structures (which I keep in an independent array) with members pointing
to a node in my directory tree, all I really need is to make sure I:

- Do not add directory nodes to me tree if no files will reference it.
(Since then, I would have no way of deleting it!)
- When the last file or directory of a node is deleted, the node itself
must be deleted as well with its recursive empty parents.

This bottum-up approach is a bit hard to explain, it works very well
however - and as I mentioned, a node can remain completely ignorant of
its childs as long as it knows its parent node.


// Cleanup rutine
for(int n=0;n < pFiles.GetCount(); n++)
{
pFile = (file*)pFiles.ElementAt(n);
// Remember folder so we can iterate "up" and clean
node* folder = pFile->dir;
// Delete the file entry
delete pFile;
// If the pFile was the only pointing to node
while(folder->parent != NULL && folder->nChildCount == 1)
{
// Then we can delete the node as it is unreferenced
node* folderCopy = folder;
folder = folderCopy->parent;
delete folderCopy;
}
folder->nChildCount--;
}

/Casper
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top