0

I was learning about the structures in C++ and got to know that if a structure in C++ has 3 variables (let each one be of some data type), then all of them are not allocated in a contiguous fashion. Is this correct?

If yes, then how much memory would be allocated to an object to that structure type?

For e.g. Let's say we have a structure like this:

struct a
{
    int x;
    int y;
    char c;
};

Now how intuitively an object of type a, must occupy some space = sizeOf(int) + sizeOf(int) + sizeOf(char). But, if they are not allocated continuously, there could be some memory locations allocated for that object, that are just present for providing some padding - i.e. the memory allocated for that object could look something like this:

xxxx[4-bytes]xxxxx[4-bytes]xxxx[1-byte]xxx

(NOTE: In the above blockquote x corresponds to a memory location of size 1 byte. I also assumed that sizeOf(int) = 4-bytes and sizeOf(char) = 1- byte.)

So in the above one, we can see that the object a occupies more than 9-bytes (because there are some memory locations (x's) used for padding.)

So, does something like this happen?

Thanks for your replies!

P.S. Please let me know if I hadn't written something clearly.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Aditya
  • 397
  • 2
  • 12

2 Answers2

3

When it comes to structs and classes, The layout is implementation-defined between compilers, os, and architecture... Some will use automatic alignment, others will use padding, some may even auto arrange it's members. If you need to know the size of a struct, use sizeof(Your Struct).

Here's a code snippet...

#include <iostream>

struct A {
    char a;  
    float b;
    int c;
};

struct B {
    float a;
    int b;
    char c;
}; 

int main() {
    std::cout << "Sizeof(A) = " << sizeof(A) << '\n';
    std::cout << "Sizeof(B) = " << sizeof(B) << '\n';
    return 0;
}

Output:

Sizeof(A) = 12
Sizeof(B) = 12

For my particular machine, I'm running Windows 7 - 64bit, It is an Intel Core2 Quad Extreme, and I'm using Visual Studio 2017 running it with C++17.

With my particular setup, both structures are being generated with a different layout, but have the same size in bytes.

In A's case...

char a; // 1 byte
// 3 bytes of padding
float b; // 4 bytes
int c; // 4 bytes (int is 32bit even on x64).

In B's case...

float a; // 4 bytes
int b; // 4 bytes
char c; // 1 byte
// 3 bytes of padding.

Also, your compiler flags and optimizations may have an effect. This isn't always guaranteed, as it is implementation-defined as stated in the standard.


--Edit--

Also, if you don't want this exact behavior there are some pragmas directives and macros such as pragma pack and alignas() that can be used to modify your implementation details. Here are a few references.

Francis Cugler
  • 7,788
  • 2
  • 28
  • 59
  • "*...some may even auto arrange it's members..*" - nonsense. For standard-layout classes the C++ standard guarantees compatibility with the C layout, which in turn is specified in the platform ABI. – rustyx Oct 31 '20 at 11:06
  • @rustyx Some compilers may do this depending on the optimizations and compiler flags. It is implementation-defined. Some CPUs with their advanced instruction sets such as MMX, SIMD(SSE), AVX, and AVX-512 might reorder certain data types for better alignment to utilize the cache better when using vector intrinsics. You may find these on high-end Intel CPUs such as the i7 & i9 extremes where you may not find them on some AMD, ARM, RISC-V, or low-end Intel CPUs. As I said, it is implementation-defined. They are free to implement their ISA as they see fit. Same with OS and Compilers. – Francis Cugler Oct 31 '20 at 12:31
0

So, structure Object variables take contiguous memory locations and the variables are stored in memory in the same order in which they are defined. Please refer to the code below you will get an idea.

struct c{
    int a;
    int b;
    int c;
};

int main()
{
    c obj;
    cout << &(obj.a) << endl; //0x7ffe128fe1c4
    cout << &(obj.b) << endl; //0x7ffe128fe1c8
    cout << &(obj.c) << endl; //0x7ffe128fe1cc
    return 0;
}

For Structures Padding Concept Refer here

Talal02
  • 162
  • 11
  • But from the link you have provided it seems like there could possibly be some padding between the memory chunks of different variables of an object? – Aditya Oct 31 '20 at 09:49
  • 1
    Yes! its backend structure that how memory is allocated. In your case you have class with char, float, int ... We know char takes 1 bytes, float and int takes 4 bytes. Memory is allocated mostly according to the maximum size of variable in your struct. Like in this case its 4 bytes... SO in case of char there will be 3 bytes padding and you will get 12 as a result of its size. – Talal02 Oct 31 '20 at 09:58