Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

GeeYouEye

macrumors 68000
Original poster
Dec 9, 2001
1,669
10
State of Denial
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?
 

hcuar

macrumors 65816
Jul 23, 2004
1,065
0
Dallas
GeeYouEye said:
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?

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.
 

GeeYouEye

macrumors 68000
Original poster
Dec 9, 2001
1,669
10
State of Denial
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++.
 

hcuar

macrumors 65816
Jul 23, 2004
1,065
0
Dallas
GeeYouEye said:
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++.

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:
 

wiseguy27

macrumors 6502
Apr 30, 2005
420
0
USA
GeeYouEye said:
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++.

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.
 

bbarnhart

macrumors 6502a
Jan 16, 2002
824
1
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.
 

wiseguy27

macrumors 6502
Apr 30, 2005
420
0
USA
bbarnhart said:
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.
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).
 

WebMongol

macrumors member
Sep 19, 2004
50
0
Bay Area, CA
GeeYouEye said:
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?

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
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.