C Structures and Dynamic Memory
Structures and Dynamic Memory
You can also use dynamic memory with structures.
This is useful when you don't know how many structs you'll need in advance, or want to save memory by only allocating what's necessary (e.g., in a car dealership program where the number of cars is not fixed).
Allocating Memory for a Struct
You can use the malloc()
function to allocate memory for a struct pointer:
Example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Car {
char brand[50];
int year;
};
int main() {
// Allocate memory for one Car struct
struct Car *ptr = (struct Car*) malloc(sizeof(struct Car));
// Check if allocation was successful
if (ptr == NULL) {
printf("Memory allocation failed.\n");
return 1; // Exit the program with an error code
}
// Set values
strcpy(ptr->brand, "Honda");
ptr->year = 2022;
// Print values
printf("Brand: %s\n", ptr->brand);
printf("Year: %d\n", ptr->year);
// Free memory
free(ptr);
return 0;
}
Example Explained
malloc()
allocates memory for one structstrcpy()
is used to copy a string into thebrand
field- We use
->
to access members through the pointer free()
is used at the end to release the memory
Note: malloc()
allocates uninitialized memory. The content will be undefined until you assign values. If you want memory initialized to zero, you can use calloc()
.
Using Arrays of Structs
You can also allocate memory for multiple structs at once, like an array:
Example: Allocate memory for 3 cars
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Car {
char brand[50];
int year;
};
int main() {
struct Car *cars = (struct Car*) malloc(3 * sizeof(struct Car));
if (cars == NULL) {
printf("Memory allocation failed.\n");
return 1 // Exit the program with an error code;
}
// Fill the data
strcpy(cars[0].brand, "Ford");
cars[0].year = 2015;
strcpy(cars[1].brand, "BMW");
cars[1].year = 2018;
strcpy(cars[2].brand, "Volvo");
cars[2].year = 2023;
// Print the data
for (int i = 0; i < 3; i++) {
printf("%s - %d\n", cars[i].brand, cars[i].year);
}
free(cars);
return 0;
}
Growing Arrays Later with realloc()
If you need more elements later, you can resize your dynamic array with realloc()
. This may move the block to a new location and returns a new pointer. Always store the result in a temporary pointer first to avoid losing the original memory if reallocation fails.
Example: Expand an array of structs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Car {
char brand[50];
int year;
};
int main() {
int count = 2;
struct Car *cars = (struct Car*) malloc(count * sizeof(struct Car));
if (cars == NULL) {
printf("Initial allocation failed.\n");
return 1;
}
// Initialize first 2 cars
strcpy(cars[0].brand, "Toyota"); cars[0].year = 2010;
strcpy(cars[1].brand, "Audi"); cars[1].year = 2019;
// Need one more car -> grow to 3
int newCount = 3;
struct Car *tmp = (struct Car*) realloc(cars, newCount * sizeof(struct Car));
if (tmp == NULL) {
// 'cars' is still valid here; free it to avoid a leak
free(cars);
printf("Reallocation failed.\n");
return 1;
}
cars = tmp; // use the reallocated block
// Initialize the new element at index 2
strcpy(cars[2].brand, "Kia");
cars[2].year = 2022;
// Print all cars
for (int i = 0; i < newCount; i++) {
printf("%s - %d\n", cars[i].brand, cars[i].year);
}
free(cars);
return 0;
}
Note: New space added by realloc()
is uninitialized. Be sure to initialize newly added elements (e.g. strcpy(cars[2].brand, "Kia"); cars[2].year = 2022;
) before using them.