Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Alignment and Padding in Structs | Structs and Memory
C Structs
course content

Course Content

C Structs

C Structs

1. Introduction to Structs
2. Pointers and Structs
3. Structs and Memory
4. Advanced Structs Usage
5. Implementing Data Structures

Alignment and Padding in Structs

Alignment

Each structure field is aligned to a boundary that is a multiple of the size of the structure's largest element.

For example, if the largest element is 4 bytes in size, then each element will be aligned on a 4-byte boundary.

This is done to speed up memory access and avoid hardware alignment problems.

c

main

copy
1234567891011121314151617181920
#include <stdio.h> // simple struct struct Example { char a; int b; double c; }; int main() { struct Example test; printf("Size of struct Example: %zu\n", sizeof(test)); printf("Address of p.x (char): %p\n", &test.a); printf("Address of p.y (int): %p\n", &test.b); printf("Address of p.c (double): %p\n", &test.c); return 0; }

The size of struct Example will be at least 16 bytes because double typically requires 8 byte alignment to be aligned on an 8-byte boundary. So the compiler will automatically add extra alignment bytes after int b so that double c starts on the correct boundary.

Padding

The char a field in the Example structure will only occupy 1 byte, since the char data type is typically 1 byte in size in C.

If the char a field is initialized with the character 'A', then only one byte will be occupied by that character, and the remaining bytes of the 'char a' field will remain uninitialized.

Note

The remaining bytes of the 'char a' field may contain garbage values that were in this memory location before the structure was initialized.

The int b field was required to make the compiler align the char a field with the int b field to demonstrate how the compiler automatically aligns and fills .

c

main

copy
123456789101112131415161718192021
#include <stdio.h> // simple struct struct Example { char a; int b; }; int main() { struct Example test = {'A'}; // fill in only one field printf("Size of struct Example: %zu\n", sizeof(test)); unsigned char* ptr = (unsigned char*)&test; for (int i = 0; i < (sizeof(test) / 2); i++) { printf("%p | value: %c\n", ptr + i, *(ptr + i)); } return 0; }

unsigned char* ptr = (unsigned char*)&test; - to view the structure byte by byte, you need to refer to memory as a sequence of bytes. The unsigned char type is used to represent unsigned bytes, allowing you to scan memory byte by byte;

(sizeof(test) / 2) - this restriction is necessary so that the loop processes only half of the structure - the char a field.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Switch to desktop for real-world practiceContinue from where you are using one of the options below

Everything was clear?

Section 3. Chapter 2
toggle bottom row

Alignment and Padding in Structs

Alignment

Each structure field is aligned to a boundary that is a multiple of the size of the structure's largest element.

For example, if the largest element is 4 bytes in size, then each element will be aligned on a 4-byte boundary.

This is done to speed up memory access and avoid hardware alignment problems.

c

main

copy
1234567891011121314151617181920
#include <stdio.h> // simple struct struct Example { char a; int b; double c; }; int main() { struct Example test; printf("Size of struct Example: %zu\n", sizeof(test)); printf("Address of p.x (char): %p\n", &test.a); printf("Address of p.y (int): %p\n", &test.b); printf("Address of p.c (double): %p\n", &test.c); return 0; }

The size of struct Example will be at least 16 bytes because double typically requires 8 byte alignment to be aligned on an 8-byte boundary. So the compiler will automatically add extra alignment bytes after int b so that double c starts on the correct boundary.

Padding

The char a field in the Example structure will only occupy 1 byte, since the char data type is typically 1 byte in size in C.

If the char a field is initialized with the character 'A', then only one byte will be occupied by that character, and the remaining bytes of the 'char a' field will remain uninitialized.

Note

The remaining bytes of the 'char a' field may contain garbage values that were in this memory location before the structure was initialized.

The int b field was required to make the compiler align the char a field with the int b field to demonstrate how the compiler automatically aligns and fills .

c

main

copy
123456789101112131415161718192021
#include <stdio.h> // simple struct struct Example { char a; int b; }; int main() { struct Example test = {'A'}; // fill in only one field printf("Size of struct Example: %zu\n", sizeof(test)); unsigned char* ptr = (unsigned char*)&test; for (int i = 0; i < (sizeof(test) / 2); i++) { printf("%p | value: %c\n", ptr + i, *(ptr + i)); } return 0; }

unsigned char* ptr = (unsigned char*)&test; - to view the structure byte by byte, you need to refer to memory as a sequence of bytes. The unsigned char type is used to represent unsigned bytes, allowing you to scan memory byte by byte;

(sizeof(test) / 2) - this restriction is necessary so that the loop processes only half of the structure - the char a field.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Switch to desktop for real-world practiceContinue from where you are using one of the options below

Everything was clear?

Section 3. Chapter 2
toggle bottom row

Alignment and Padding in Structs

Alignment

Each structure field is aligned to a boundary that is a multiple of the size of the structure's largest element.

For example, if the largest element is 4 bytes in size, then each element will be aligned on a 4-byte boundary.

This is done to speed up memory access and avoid hardware alignment problems.

c

main

copy
1234567891011121314151617181920
#include <stdio.h> // simple struct struct Example { char a; int b; double c; }; int main() { struct Example test; printf("Size of struct Example: %zu\n", sizeof(test)); printf("Address of p.x (char): %p\n", &test.a); printf("Address of p.y (int): %p\n", &test.b); printf("Address of p.c (double): %p\n", &test.c); return 0; }

The size of struct Example will be at least 16 bytes because double typically requires 8 byte alignment to be aligned on an 8-byte boundary. So the compiler will automatically add extra alignment bytes after int b so that double c starts on the correct boundary.

Padding

The char a field in the Example structure will only occupy 1 byte, since the char data type is typically 1 byte in size in C.

If the char a field is initialized with the character 'A', then only one byte will be occupied by that character, and the remaining bytes of the 'char a' field will remain uninitialized.

Note

The remaining bytes of the 'char a' field may contain garbage values that were in this memory location before the structure was initialized.

The int b field was required to make the compiler align the char a field with the int b field to demonstrate how the compiler automatically aligns and fills .

c

main

copy
123456789101112131415161718192021
#include <stdio.h> // simple struct struct Example { char a; int b; }; int main() { struct Example test = {'A'}; // fill in only one field printf("Size of struct Example: %zu\n", sizeof(test)); unsigned char* ptr = (unsigned char*)&test; for (int i = 0; i < (sizeof(test) / 2); i++) { printf("%p | value: %c\n", ptr + i, *(ptr + i)); } return 0; }

unsigned char* ptr = (unsigned char*)&test; - to view the structure byte by byte, you need to refer to memory as a sequence of bytes. The unsigned char type is used to represent unsigned bytes, allowing you to scan memory byte by byte;

(sizeof(test) / 2) - this restriction is necessary so that the loop processes only half of the structure - the char a field.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Switch to desktop for real-world practiceContinue from where you are using one of the options below

Everything was clear?

Alignment

Each structure field is aligned to a boundary that is a multiple of the size of the structure's largest element.

For example, if the largest element is 4 bytes in size, then each element will be aligned on a 4-byte boundary.

This is done to speed up memory access and avoid hardware alignment problems.

c

main

copy
1234567891011121314151617181920
#include <stdio.h> // simple struct struct Example { char a; int b; double c; }; int main() { struct Example test; printf("Size of struct Example: %zu\n", sizeof(test)); printf("Address of p.x (char): %p\n", &test.a); printf("Address of p.y (int): %p\n", &test.b); printf("Address of p.c (double): %p\n", &test.c); return 0; }

The size of struct Example will be at least 16 bytes because double typically requires 8 byte alignment to be aligned on an 8-byte boundary. So the compiler will automatically add extra alignment bytes after int b so that double c starts on the correct boundary.

Padding

The char a field in the Example structure will only occupy 1 byte, since the char data type is typically 1 byte in size in C.

If the char a field is initialized with the character 'A', then only one byte will be occupied by that character, and the remaining bytes of the 'char a' field will remain uninitialized.

Note

The remaining bytes of the 'char a' field may contain garbage values that were in this memory location before the structure was initialized.

The int b field was required to make the compiler align the char a field with the int b field to demonstrate how the compiler automatically aligns and fills .

c

main

copy
123456789101112131415161718192021
#include <stdio.h> // simple struct struct Example { char a; int b; }; int main() { struct Example test = {'A'}; // fill in only one field printf("Size of struct Example: %zu\n", sizeof(test)); unsigned char* ptr = (unsigned char*)&test; for (int i = 0; i < (sizeof(test) / 2); i++) { printf("%p | value: %c\n", ptr + i, *(ptr + i)); } return 0; }

unsigned char* ptr = (unsigned char*)&test; - to view the structure byte by byte, you need to refer to memory as a sequence of bytes. The unsigned char type is used to represent unsigned bytes, allowing you to scan memory byte by byte;

(sizeof(test) / 2) - this restriction is necessary so that the loop processes only half of the structure - the char a field.

Task

  1. Create an unsigned char pointer to the test structure to traverse the allocated memory byte byte and perform explicit type casting;
  2. In the loop conditions, specify the correct number of iterations to display all memory addresses of the char a field;
  3. In the printf() function, write the correct expression to display addresses, taking into account address arithmetic.

Switch to desktop for real-world practiceContinue from where you are using one of the options below
Section 3. Chapter 2
Switch to desktop for real-world practiceContinue from where you are using one of the options below
We're sorry to hear that something went wrong. What happened?
some-alt