Using the sizeof operator on a struct?

Discussion in 'C++' started by Peter Koch Larsen, Aug 23, 2004.

  1. "Casper" <> skrev i en meddelelse
    news:KzrWc.77021$...
    > 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
    Peter Koch Larsen, Aug 23, 2004
    #1
    1. Advertising

  2. Peter Koch Larsen

    Dave Guest

    "Casper" <> wrote in message
    news:KzrWc.77021$...
    > 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).
    Dave, Aug 23, 2004
    #2
    1. Advertising

  3. Peter Koch Larsen

    Dave Guest

    "Casper" <> wrote in message
    news:yasWc.78772$...
    >
    > > 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


    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...
    Dave, Aug 23, 2004
    #3
  4. Peter Koch Larsen

    Steve Guest

    On 23/8/04 11:31 pm, in article
    KzrWc.77021$, "Casper" <>
    wrote:

    > 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.
    Steve, Aug 23, 2004
    #4
  5. Peter Koch Larsen

    Casper Guest

    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
    Casper, Aug 23, 2004
    #5
  6. Peter Koch Larsen

    Casper Guest


    > 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
    Casper, Aug 24, 2004
    #6
  7. Peter Koch Larsen

    Casper Guest

    > 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
    Casper, Aug 24, 2004
    #7
  8. Peter Koch Larsen

    Siemel Naran Guest

    "Casper" <> wrote in message news:rZxWc.86262

    > 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 :(.
    Siemel Naran, Aug 24, 2004
    #8
  9. Peter Koch Larsen

    Casper Guest

    > 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;
    }
    Casper, Aug 24, 2004
    #9
  10. Casper wrote:
    >
    > > 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;
    > }


    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.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Aug 24, 2004
    #10
  11. Peter Koch Larsen

    Casper Guest

    Thanks for the clarification!
    Casper
    Casper, Aug 24, 2004
    #11
  12. Peter Koch Larsen

    Casper Guest

    > 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
    Casper, Aug 24, 2004
    #12
  13. Peter Koch Larsen

    Siemel Naran Guest

    "Casper" <> wrote in message news:kWJWc.110624

    > 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?
    Siemel Naran, Aug 25, 2004
    #13
  14. Peter Koch Larsen

    Casper Guest

    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


    Siemel Naran wrote:
    > "Casper" <> wrote in message news:kWJWc.110624
    >
    >
    >>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?
    >
    >
    Casper, Aug 26, 2004
    #14
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Derek
    Replies:
    7
    Views:
    24,305
    Ron Natalie
    Oct 14, 2004
  2. Trevor

    sizeof(str) or sizeof(str) - 1 ?

    Trevor, Apr 3, 2004, in forum: C Programming
    Replies:
    9
    Views:
    616
    CBFalconer
    Apr 10, 2004
  3. Chris Fogelklou
    Replies:
    36
    Views:
    1,356
    Chris Fogelklou
    Apr 20, 2004
  4. Manish_Ganvir
    Replies:
    13
    Views:
    1,559
    Keith Thompson
    Feb 14, 2005
  5. Kislay

    The sizeof operator : sizeof(++i)

    Kislay, Oct 18, 2007, in forum: C Programming
    Replies:
    10
    Views:
    673
    Peter Pichler
    Oct 19, 2007
Loading...

Share This Page