This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
struct a
{
char *c;
char b;
};
What is sizeof(a)?
#include <stdio.h>
typedef struct { char* c; char b; } a;
int main()
{
printf("sizeof(a) == %d", sizeof(a));
}
I get "sizeof(a) == 8", on a 32-bit machine. The total size of the structure will depend on the packing: In my case, the default packing is 4, so 'c' takes 4 bytes, 'b' takes one byte, leaving 3 padding bytes to bring it to the next multiple of 4: 8. If you want to alter this packing, most compilers have a way to alter it, for example, on MSVC:
#pragma pack(1)
typedef struct { char* c; char b; } a;
gives sizeof(a) == 5. If you do this, be careful to reset the packing before any library headers!
Contrary to what some of the other answers have said, on most systems, in the absence of a pragma or compiler option, the size of the structure will be at least 6 bytes and, on most 32-bit systems, 8 bytes. For 64-bit systems, the size could easily be 16 bytes. Alignment does come into play; always. The sizeof a single struct has to be such that an array of those sizes can be allocated and the individual members of the array are sufficiently aligned for the processor in question. Consequently, if the size of the struct was 5 as others have hypothesized, then an array of two such structures would be 10 bytes long, and the char pointer in the second array member would be aligned on an odd byte, which would (on most processors) cause a major bottleneck in the performance.
If you want to manually count it, the size of a struct is just the size of each of its data members after accounting for alignment. There's no magic overhead bytes for a struct.
The exact value is sizeof(a).
You might also take a risk and assume that it is in this case no less than 2 and no greater than 16.
This will vary depending on your architecture and how it treats basic data types. It will also depend on whether the system requires natural alignment.
I assume you mean struct and not strict, but on a 32-bit system it'll be either 5 or 8 bytes, depending on if the compiler is padding the struct.
I suspect you mean 'struct', not 'strict', and 'char' instead of 'Char'.
The size will be implementation dependent. On most 32-bit systems, it will probably be 5 -- 4 bytes for the pointer, one for the char. I don't believe alignment will come into play here. If you swapped 'c' and 'b', however, the size may grow to 8 bytes.
Ok, I tried it out (g++ 4.2.3, with -g option) and I get 8.
The sizeof the structure should be 8 bytes on a 32 bit system, so that the size of the structure becomes multiple of 2. This makes individual structures available at the correct byte boundaries when an array of structures is declared. This is achieved by padding the structure with 3 bytes at the end.
If the structure had the pointer declared after the char, it would still be 8 bytes in size
but the 3 byte padding would have been added to keep the pointer (which is a 4 byte element) aligned at a 4 byte address boundary.
The rule of thumb is that elements should be at an offset which is the multiple of their byte size and the structure itself should be of a size which is a multiple of 2.
Related
I have a system that can run either 32 or 64 bit. If I define a structure with 7 longs and 1 char, then I understand that if the structure runs on 32 bits, a long will be assigned 32 bits, a char will be assigned 8 bits and the structure will require at least 232 bits. But if the structure runs on 64 bits, then a long will be assigned 64 bits, a char will be assigned 8 bits and the structure will require at least 456 bits. I also understand that the memory will be optimized for arrays of a structure if the structure requires a power of 2 bits. This structure, then, will have to fill 256 bits on a 32 bit system or 512 bits on a 64 bit system. Will that padding be automatically added to the structure to optimize the memory, or should I add something to the structure to bring it closer to a power of 2 bits in order to optimize the processing of an array of those structures?
Edit: Just saw the article about array indexing using shifts vs multiplication. My advice would be to size the structs appropriately for your data, taking care not to waste space due to slop if you can help it. If a profiler determines that indexing elements is the major performance hit for you, you can try adding slop to specifically reach a specific byte size. However, my intuition tells me (on a modern system with caches), you'll suffer a bigger performance hit by needlessly increasing the size of your structures and pushing useful memory out of cache! :D
(Original response follows)
I don't think you'll see a performance penalty from not having your structure sized to a power of two. The performance issue with arrays of structs is typically due to alignment.
Alignment and Performance
In order to minimize the number of instructions required to access a scalar variable, the variable has to exist at a location in memory that is a multiple of its size in bytes. The implication for structures is as follows:
Practically speaking, since the address of a struct is equal to the address of its first member, the beginning address of a given struct has to be a multiple of the size of its first member, in bytes
For compiler writers, the pragmatic approach is to align structures to a multiple of the widest scalar value they contain
Arrays of structs are allocated with padding between them to guarantee that these alignment guarantees hold over the entire array - most compilers will do this for you! :)
Padding is also added between variables in the struct, if necessary to ensure that all structure members are properly aligned
Dealing with Structure Alignment
Most compilers on modern systems will automatically add padding after the structure in order to satisfy alignment requirements for self-aligned types.
So, in general, your structure will be aligned to a multiple of the largest element in the structure. As a result of the longs in your struct, each struct in an array will be spaced such that the beginning address of each is a multiple of sizeof(long). This is accomplished by transparently adding "slop" to the end of your struct. Try this and see what you get:
#include <stdio.h>
struct my_struct
{
long l1;
long l2;
long l3;
long l4;
long l5;
long l6;
long l7;
char c;
};
int main( int argc, char** argv )
{
printf("sizeof(my_struct) == %lu\n", sizeof(struct my_struct));
return 0;
};
/* EOF */
A Note on Packing:
In general, for self-aligned types on systems which support them you can usually use __attribute__((packed)) but this will likely result in a performance penalty as the number of machine instructions required to access a given member will be increased.
If you really care about not wasting space due to alignment slop and you don't need the full range of values in one of those longs, see if you can move that char into one of the longs with a mask or try using bitfields.
One of my personal favorite resources on structure packing and alignment: The Lost Art of C Structure Packing
Will that padding be automatically added to the structure to optimize
the memory, or should I add something to the structure to bring it
closer to a power of 2 bits in order to optimize the processing of an
array of those structures?
No, you don't need to add anything to your struct declaration. Generally speaking alignment and padding is taken care of by the compiler.
You can test that yourself by printing the output of sizeof(your_struct);.
It is however possible to do the opposite and optimize for size instead of speed. This can be useful is memory is scare or if you send your raw struct over the network. GCC has __attribute__((packed)) to do this.
This is a bit late, but I just want to share this article about structure packing with details on how to optimize the size of the struct variables with rearrangement of the order of declaration of the struct members:
http://www.catb.org/esr/structure-packing/
#include <stdio.h>
int main()
{
struct {
int a : 1; // bit field sized 1
double b;
}structVar;
//structVar.a = 10;
printf("%d",sizeof(structVar));
}
size of structVar is 16 at gcc compiler on linux machine.
According to me it should be 9. 8 for double and 1 for int bit field.
Any idea Why ?
Structure is aligned (and padded) to size of its largest member - in that case, to sizeof(double). This is expected (although not required by standard) and predictable. It doesn't matter if second member would be int, short or whatever, - as long as it is smaller than double, sizeof struct will be 16.
Structure packing may reduce size of structure. E.g. gcc allows to #pragma pack(n) to set new alignment for subsequent structures, so with alignment 4 it will be 12 bytes.
Reason is, if you'll have array of this structures, second structure will be unaligned. It may have performance hits or even failures on some CPUs.
Most probably because the double required 8-byte alignment, as the comments stated. But anyway this is completely implementation-defined (that's why sizeof exists in the first place).
This is because of padding. double must be aligned by 8 bytes. Hence, extra 7 bytes and 7 bits are padded to this structure.
You can refer this link.
There are compiler specific options to turn off the padding. But they are not recommended for the sake of compatibility.
#include<stdio.h>
struct krishna {
int i,j,k,l,m;
char c;
double d;
char g[48];
};
int main() {
struct krishna *me={0};
printf("%ld %ld\n",sizeof(me),sizeof(*me));//output is 8 80 how??
return 0;
}
Hello everyone I am new here and the compiler I use is gcc compiler in the above code can anyone explain why
1) pointer irrespective of any type is allocated 8 ?
2) sizeof the above struct is 80 ? Can anyone explain to me in general for any structure how can one determine the structure size , I am getting confused each time I expect one value but getting a different answer and I have also read other questions and answers in stack overflow regarding this and I am still not getting it.Please help.
printf("%ld %ld\n",sizeof(me),sizeof(*me));//output is 8 80 how??
Actually that should be:
printf("%zu %zu\n",sizeof(me),sizeof(*me));//output is 8 80 how??
"%zu" is the correct format string for a size_t value, such as the value you get from sizeof. "%ld" may happen to work on some systems (and apparently it does on yours), but you shouldn't count on that.
If your compiler doesn't support "%zu", you can use "%lu" (which expects an unsigned long argument) and explicitly convert the arguments:
printf("%lu %lu\n", (unsigned long)sizeof(me), (unsigned long)sizeof(*me));
You're getting 8 for sizeof(me) because that happens to be the size of a pointer on the compiler you're using (8 bytes, 64 bits). If you compiled and ran your program on a different system, you might get 4, because a lot of systems have 32-bit pointers. (And this assumes a byte is 8 bits, which is true for most systems but not guaranteed by the language.)
Most compilers make all pointers the same size, but that's not guaranteed by the language either. For example, on a word-addressed machine, an int* pointer could be just a machine-level address, but a char* pointer might need additional information to specify which byte within the word it points to. You're not very likely to run into a system with varying pointer sizes, but there's still no point in assuming that all pointers are the same size.
As for the size of the structure, that also can vary from one compiler to another. Here's your structure again:
struct krishna {
int i,j,k,l,m;
char c;
double d;
char g[48];
};
char is always exactly 1 byte, and char[48] is always exactly 48 bytes.
The number of bytes in an int can vary from one system to another; 4 bytes is most common these days.
The size of a double is typically 8 bytes, but this can also vary (though I don't think I've ever seen a system where sizeof (double) isn't 8 bytes.)
Structure members are laid out in the order in which they're declared, so your i will be at the very beginning of the structure, followed by j, k, and so forth.
Finally, the compiler will often insert padding bytes between members, or after the last member, so that each member is properly aligned. For example, on many systems a 4-byte int needs to be aligned at an offset that's a multiple of 4 bytes; if it's misaligned, access to it may be slow and/or very difficult.
The fact that sizeof (struct krishna) happens to be 80 bytes on your system isn't really all that important. It's more important to understand (a) the general rules compilers use to determine how structures are laid out, and (b) the fact that those rules can result in different layouts for different systems.
The language definition and your compiler guarantee that you can have objects of type struct krishna, and that you can access those objects and their members, getting back whatever values you stored in them. If you need to know how big a struct krishna is, the answer is simply sizeof (struct krishna). If, for some reason, you need to know more details than that (say, if you need to match some externally imposed layout), you can do some experiments and/or consult your compiler's documentation -- but be aware that the specifics will apply only to the compiler you're using on the system where you're using it. (Often an ABI for your system will constrain the compiler's choices.)
You can also use sizeof and offsetof (look it up) to find out where each member is allocated.
All pointers are addresses, and all addresses are the same size on a given system, usually 4 bytes on a 32 bit system and 8 bytes on a 64 bit system. Since you are getting 8, you must be on a 64 bit system.
The size of a struct depends on how the compiler "packs" the individual fields of the struct together into a single block of memory to contain the entire struct. In your case, your struct has 5 int fields (4 bytes each), a single char field (1 byte), a single double field (8 bytes), and a 48 character array. Add all that up and you get 20 + 1 + 8 + 48 = 77 bytes to store your data. The actual size is 80 because the compiler is "padding" the 1 byte char field with 3 extra unused bytes in order to keep all fields in the struct aligned to a 4-byte memory address, which is needed for good performance.
Hope that helps!
This is because:
sizeof( me ) // is a pointer.
... me is a pointer. The size of a pointer is a multiple of the word on your environment, hence it's common that on 32-bit environments a pointer is 4 bytes whereas on a 64-bit environment a pointer is 8 bytes (but not written in stone). If you were to go back a couple years, a 16-bit environment would have a 2 byte pointer. Looking at the next sizeof:
sizeof( *me ) // is a struct krishna, hence 80 bytes are needed to store it in memory.
... is a structure and the size of the structure krishna is 80 bytes. If you look at the structure:
struct krishna {
int i,j,k,l,m; // sizeof( int ) * 5
char c; // sizeof( char ) * 1
double d; // sizeof( double ) * 1
char g[48]; // sizeof( char ) * 48
// padding for memory address offset would be here.
};
... if you add up the amount of bytes required for each field and include the appropriate data structure alignment for the memory address offset then it will total 80 bytes (as expected). The reason it adds an extra 3 unused bytes is because to store a structure in memory it must be in a continuous block of memory that is allocated for the structure. For performance reasons, it will pad any size issues to ensure that the memory addresses are always a multiple of the word. The tradeoff of the 3 bytes for performance improvements is worth it, 3 bytes nowadays is not as impactful as the performance improvements the processor has when data alignment is guaranteed.
Just to add to answers of #Jacob Pollack and #ObjetDart, you can find more about structure padding at Structure padding in C.
This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?
Consider the following C code:
#include <stdio.h>
struct employee
{
int id;
char name[30];
};
int main()
{
struct employee e1;
printf("%d %d %d", sizeof(e1.id), sizeof(e1.name), sizeof(e1));
return(0);
}
The output is:
4 30 36
Why is the size of the structure not equal to the sum of the sizes of its individual component variables?
The compiler may add padding for alignment requirements. Note that this applies not only to padding between the fields of a struct, but also may apply to the end of the struct (so that arrays of the structure type will have each element properly aligned).
For example:
struct foo_t {
int x;
char c;
};
Even though the c field doesn't need padding, the struct will generally have a sizeof(struct foo_t) == 8 (on a 32-bit system - rather a system with a 32-bit int type) because there will need to be 3 bytes of padding after the c field.
Note that the padding might not be required by the system (like x86 or Cortex M3) but compilers might still add it for performance reasons.
As mentioned, the C compiler will add padding for alignment requirements. These requirements often have to do with the memory subsystem. Some types of computers can only access memory lined up to some 'nice' value, like 4 bytes. This is often the same as the word length. Thus, the C compiler may align fields in your structure to this value to make them easier to access (e.g., 4 byte values should be 4 byte aligned) Further, it may pad the bottom of the structure to line up data which follows the structure. I believe there are other reasons as well. More info can be found at this wikipedia page.
Your default alignment is probably 4 bytes. Either the 30 byte element got 32, or the structure as a whole was rounded up to the next 4 byte interval.
Aligning to 6 bytes is not weird, because it is aligning to addresses multiple to 4.
So basically you have 34 bytes in your structure and the next structure should be placed on the address, that is multiple to 4. The closest value after 34 is 36. And this padding area counts into the size of the structure.
Is bitfield a C concept or C++?
Can it be used only within a structure? What are the other places we can use them?
AFAIK, bitfields are special structure variables that occupy the memory only for specified no. of bits. It is useful in saving memory and nothing else. Am I correct?
I coded a small program to understand the usage of bitfields - But, I think it is not working as expected. I expect the size of the below structure to be 1+4+2 = 7 bytes (considering the size of unsigned int is 4 bytes on my machine), But to my surprise it turns out to be 12 bytes (4+4+4). Can anyone let me know why?
#include <stdio.h>
struct s{
unsigned int a:1;
unsigned int b;
unsigned int c:2;
};
int main()
{
printf("sizeof struct s = %d bytes \n",sizeof(struct s));
return 0;
}
OUTPUT:
sizeof struct s = 12 bytes
Because a and c are not contiguous, they each reserve a full int's worth of memory space. If you move a and c together, the size of the struct becomes 8 bytes.
Moreover, you are telling the compiler that you want a to occupy only 1 bit, not 1 byte. So even though a and c next to each other should occupy only 3 bits total (still under a single byte), the combination of a and c still become word-aligned in memory on your 32-bit machine, hence occupying a full 4 bytes in addition to the int b.
Similarly, you would find that
struct s{
unsigned int b;
short s1;
short s2;
};
occupies 8 bytes, while
struct s{
short s1;
unsigned int b;
short s2;
};
occupies 12 bytes because in the latter case, the two shorts each sit in their own 32-bit alignment.
1) They originated in C, but are part of C++ too, unfortunately.
2) Yes, or within a class in C++.
3) As well as saving memory, they can be used for some forms of bit twiddling. However, both memory saving and twiddling are inherently implementation dependent - if you want to write portable software, avoid bit fields.
Its C.
Your comiler has rounded the memory allocation to 12 bytes for alignment purposes. Most computer memory syubsystems can't handle byte addressing.
Your program is working exactly as I'd expect. The compiler allocates adjacent bitfields into the same memory word, but yours are separated by a non-bitfield.
Move the bitfields next to each other and you'll probably get 8, which is the size of two ints on your machine. The bitfields would be packed into one int. This is compiler specific, however.
Bitfields are useful for saving space, but not much else.
Bitfields are widely used in firmware to map different fields in registers. This save a lot of manual bitwise operations which would have been necessary to read / write fields without it.
One disadvantage is you can't take address of bitfields.