C++ struct overhead?

Discussion in 'Mac Programming' started by GeeYouEye, Aug 18, 2005.

  1. GeeYouEye macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
    #1
    I know that in straight C, the address of a struct is the address of the first member thereof. My situation is that I have an array of structs, each of which contains a single data member, an array (fixed-size)of characters. The question is, since in C++ structs are a special case of classes apparently (read that on cplusplus.com), can I still depend on the member memory to be consecutive, and is there any class overhead at the beginning or end of the struct that I have to worry about if I want to use pointer arithmetic go through the array?
     
  2. hcuar macrumors 65816

    hcuar

    Joined:
    Jul 23, 2004
    Location:
    Dallas
    #2
    Pointer arithmetic on an array of structs is dangerous... The array may be word aligned and therefore not layed out as expected. You should always use the array brackets and then the dot notation to access members of a struct in an array. The compilers tend to do nifty packing unless you utilize pragma pack and bit fields in the definition.

    Good luck.
     
  3. GeeYouEye thread starter macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
    #3
    I doubt I have to worry about the word-alignment issue; the only member is a 512-char array. That should align just fine. The only question is: is there overhead like there is in regular classes in C++.
     
  4. hcuar macrumors 65816

    hcuar

    Joined:
    Jul 23, 2004
    Location:
    Dallas
    #4
    No overhead...

    I would look at the memory in the debugger to make sure about the alignment... I'm an embedded software engineer, and word alignment is often a downfall for new programmers. If you "doubt", you better check. :rolleyes:
     
  5. GeeYouEye thread starter macrumors 68000

    GeeYouEye

    Joined:
    Dec 9, 2001
    Location:
    State of Denial
  6. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #6
    All that hcuar has stated is true (and the advice given is also highly recommended). I'm not sure what overhead you're referring to in the storage definition of a class in C++. The only difference between structs and classes in C++ is the default member access (which is public in structs and private in classes), although by convention people use structs for data definitions and classes for data/function combinations.

    If your struct/class has only one member (like your 512 char array) you should be fine using a pointer to traverse through it. If there are multiple members, then the order of the members in memory is not defined and is compiler dependent (so on one platform the members may be stored in memory in the order of declaration and on another they may be in the reverse order of declaration). If you're sure you want to sacrifice portability and use pointers to traverse through struct members, then experimenting with some sample programs would tell you how your pointer should be manipulated.

    Generally, avoiding pointers to traverse through multiple struct/class members is a good idea.
     
  7. bbarnhart macrumors 6502a

    bbarnhart

    Joined:
    Jan 16, 2002
    Location:
    Stilwell, Kansas
    #7
    I'm not sure with Mac compilers, but it is true on Windows compilers (MS VC++) that if you have a to specifically pack structs.

    struct Character
    {
    char c;
    };

    is probably really taking up 4 bytes. You would need to add

    #pragma pack 1

    to make it really only use one byte.
     
  8. wiseguy27 macrumors 6502

    wiseguy27

    Joined:
    Apr 30, 2005
    Location:
    USA
    #8
    Yes, padding structs is a compiler "feature" but it's different on different platforms. Even C/C++ compilers on different Unices (Linux, BSD, HP-UX, AIX, Solaris) would do it while optimizing the code. Padding and order of variables in memory are the main reasons pointers are a no-no within structs/classes (to traverse across members).
     
  9. WebMongol macrumors member

    Joined:
    Sep 19, 2004
    Location:
    Bay Area, CA
    #9
    In C++ memory representation of struct and class objects without virtual functions is identical to C representation of struct.
    Objects of classes that have at least one virtual function contain an additional hidden data member called vptr. Vptr points to the vtbl -- a per-class table of the virtual functions' addresses.
    Following test program illustrate this point:

    // g++ struct_size.cc -o xstruct_size && ./xstruct_size
    #include <stdio.h>

    struct S1 {
    int x;
    };
    class C1 {
    public:
    int x;
    };

    class C2 {
    public:
    int x;
    virtual void vf() { ++x; }
    };
    struct MemoryLayoutOfC2 {
    void* vptr; // gcc version 3.3 20030304 (Apple Computer, Inc. build 1666)
    // places the vptr as the first data member of the object
    int x;
    };

    int main(int argc, char** argv)
    {
    printf("Sizes of S1: %lu C1: %lu C2: %lu\n", sizeof(S1), sizeof(C1), sizeof(C2));
    C2 c2;
    printf("Address c2 obj: %p and c2.x member: %p\n", &c2, &c2.x);
    return 0;
    }

    Following is an output of this program:

    mac:~/play/$ g++ struct_size.cc -o xstruct_size && ./xstruct_size
    Sizes of S1: 4 C1: 4 C2: 8
    Address c2 obj: 0xbffffbc0 and c2.x member: 0xbffffbc4

    Object of c2 have an additional hidden member - vptr that occupies extra four bytes. struct MemoryLayoutOfC2 shows actual memory layout of C2 object.

    For additional details check any good paper that describes C++ object model, for example:

    - http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=195

    - or book by Stanley B. Lippman: Inside the C++ Object Model
     

Share This Page