Anyone care to tell me why this is 24 bytes?
-
char [10] = 10 bytes unsigned int= 4 bytes char [1] = 1 byte MAJOR = 4 bytes 10 + 4 + 1 + 4 = 19 bytes but it outputs 24 bytes!!
typedef enum { CS, MIS, ME, PHI }MAJOR; typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; int main(void) { printf("%d\n", sizeof(STUDENT)); return 0; }
----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented". -
char [10] = 10 bytes unsigned int= 4 bytes char [1] = 1 byte MAJOR = 4 bytes 10 + 4 + 1 + 4 = 19 bytes but it outputs 24 bytes!!
typedef enum { CS, MIS, ME, PHI }MAJOR; typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; int main(void) { printf("%d\n", sizeof(STUDENT)); return 0; }
----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".I'm just stabbing this one, but the other 5 bytes are for the struct, sepearately its 19bytes but within a struct, you allow a little more room. Discovery consist of seeing what everybody has seen and thinking what nobody has thought -- Albert Szent-Györgyi Name the greatest of all the inventors: accident --Mark Twain
-
char [10] = 10 bytes unsigned int= 4 bytes char [1] = 1 byte MAJOR = 4 bytes 10 + 4 + 1 + 4 = 19 bytes but it outputs 24 bytes!!
typedef enum { CS, MIS, ME, PHI }MAJOR; typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; int main(void) { printf("%d\n", sizeof(STUDENT)); return 0; }
----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".I think you have the Struct Member Alignment set to 4 bytes (see option under Project/Settings/c++/code generation). For the struct you have shown the total size of the struct would then be 24 bytes. As it says in MSDN: The Struct Member Alignment (/Zpn) option controls how the members of a structure are packed into memory and specifies the same packing for all structures in a module. When you specify this option, each structure member after the first is stored on either the size of the member type or n-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.
-
char [10] = 10 bytes unsigned int= 4 bytes char [1] = 1 byte MAJOR = 4 bytes 10 + 4 + 1 + 4 = 19 bytes but it outputs 24 bytes!!
typedef enum { CS, MIS, ME, PHI }MAJOR; typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; int main(void) { printf("%d\n", sizeof(STUDENT)); return 0; }
----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".In a word: boundary alignment. ID is an unsigned int and MAJOR, an enum, also defaults to an int datatype. Ints are 4-byte fields that are naturally aligned on four byte boundarys. Therefore the compiler places the int fields on four byte boundarys. Doubles go on an eight byte boundary. If the struct does not have the fields ordered in descend size of datatypes, (doubles, ints, short ints and finally char/char array), then the compiler silently inserts unreachable filler alignment bytes. Doubles, ints, etc. are boundary aligned to improve register load performance. On certain types of machines fetching unaligned data can cause an execption. You can use a #pragma to modify the default boundary alighment. You can see the result of what the compiler has done by generating a listing that details the struct. Offset length Field 0 10 name 10 2 unreachable filler inserted by the compiler 12 4 ID 16 1 sex 17 3 unreachable filler inserted by the compiler 20 4 major Total length=24 Sam
-
char [10] = 10 bytes unsigned int= 4 bytes char [1] = 1 byte MAJOR = 4 bytes 10 + 4 + 1 + 4 = 19 bytes but it outputs 24 bytes!!
typedef enum { CS, MIS, ME, PHI }MAJOR; typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; int main(void) { printf("%d\n", sizeof(STUDENT)); return 0; }
----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".hi Alex, Visual C++ ( for that matter most C++ compilers ) has got some thing called structure alignment. For the efficient access of the memory they align varibles at the DWORD boundary. Even though name is taking only 10 bytes. The value of ID is from byte 12 to 16 . Even though sex takes only 1 byte , Major starts only at the 20th byte. And the size will be rounded to nearest DWORD (that is 24 ) u can use a pragma to make it one byte aligned. #pragma pack(1) typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; #pragma pack(4) now the size will be 19 as u said. Praseed Pai www.praseedpai.com
-
hi Alex, Visual C++ ( for that matter most C++ compilers ) has got some thing called structure alignment. For the efficient access of the memory they align varibles at the DWORD boundary. Even though name is taking only 10 bytes. The value of ID is from byte 12 to 16 . Even though sex takes only 1 byte , Major starts only at the 20th byte. And the size will be rounded to nearest DWORD (that is 24 ) u can use a pragma to make it one byte aligned. #pragma pack(1) typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; #pragma pack(4) now the size will be 19 as u said. Praseed Pai www.praseedpai.com
Thanks guys for all your replies. Hi Praseed, That's interesting. Would you tell me what does the following do? Also, why would the nearest DWORD be 24 bytes? #pragma pack(1) ... #pragma pack(4) Another question is on the DWORD. Isn't DWORD a macro for an integer type? When do we use DWORD? Thanks ----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".
-
Thanks guys for all your replies. Hi Praseed, That's interesting. Would you tell me what does the following do? Also, why would the nearest DWORD be 24 bytes? #pragma pack(1) ... #pragma pack(4) Another question is on the DWORD. Isn't DWORD a macro for an integer type? When do we use DWORD? Thanks ----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".
hi Alex, DWORD is not a macro for integer type. i feel it is a typedef typedef unsigned long DWORD. Win32 code is running on a 32-bit processor . So accessing memory at DWORD ( 4 byte aligment ) will speed things up. Visual C++ is padding to the nearest DWORD boundary to maximize performance when u have declared something like this. STUDENT x[10]; #pragma pack(1) makes the structure aligment into 1 and it will behave the way u expected it to be . ideal usage should be #pragma pack(push) //push the current settings into pragma stack #pragam pack(1) // Declare the student structure here #pragma pack(pop) Hope this helps Praseed Pai www.praseedpai.com
-
hi Alex, DWORD is not a macro for integer type. i feel it is a typedef typedef unsigned long DWORD. Win32 code is running on a 32-bit processor . So accessing memory at DWORD ( 4 byte aligment ) will speed things up. Visual C++ is padding to the nearest DWORD boundary to maximize performance when u have declared something like this. STUDENT x[10]; #pragma pack(1) makes the structure aligment into 1 and it will behave the way u expected it to be . ideal usage should be #pragma pack(push) //push the current settings into pragma stack #pragam pack(1) // Declare the student structure here #pragma pack(pop) Hope this helps Praseed Pai www.praseedpai.com
Hi praseed, Thanks for your reply. So, when do we use DWORD in C/C++? There is a lot of DWORD value in the registry in the windows OS, but not sure when to use it in programming. Thanks ----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".
-
Hi praseed, Thanks for your reply. So, when do we use DWORD in C/C++? There is a lot of DWORD value in the registry in the windows OS, but not sure when to use it in programming. Thanks ----------------------------- C++ without virtual functions is not OO. Programming with classes but without dynamic binding is called "object based", but not "object oriented".
Hi , This is the defenition of DWORD in one of the microsoft's header file. typedef unsigned long DWORD; usigned long is only 4 bytes (32 bits ) on Intel and AMD 32 bit platform. ( ur confusion might have started from the fact that java long is 8 bytes ) if u use DWORD (win32 data types ) , ur code can be ported to 64-bit platforms without much problem ( at least that is what ms says ). i feel , microsoft will make sure that DWORD is always 32 bits . Where as they cannot say the thing sure about c types like int , long etc. (with IA-64 or AMD-64 !) praseed pai www.praseedpai.com
-
hi Alex, Visual C++ ( for that matter most C++ compilers ) has got some thing called structure alignment. For the efficient access of the memory they align varibles at the DWORD boundary. Even though name is taking only 10 bytes. The value of ID is from byte 12 to 16 . Even though sex takes only 1 byte , Major starts only at the 20th byte. And the size will be rounded to nearest DWORD (that is 24 ) u can use a pragma to make it one byte aligned. #pragma pack(1) typedef struct STUDENT_t { char name[10]; unsigned int ID; char sex[1]; MAJOR major; }STUDENT; #pragma pack(4) now the size will be 19 as u said. Praseed Pai www.praseedpai.com
By default, data items are aligned to a boundary that matches their size - not necessarily a DWORD. A short will be aligned on a two-byte boundary, a char on a one-byte boundary, and a double on an eight-boundary. Also, the best way to use the pack pragma is to save and restore the previous alignment. This is done as follows : #pragma pack(push, 1) // saves old packing and sets it to 1 ... #pragma pack(pop) // restores previous packing __________________________________________ a two cent stamp short of going postal.