Safe Memory Handling
Best Practices for Memory Management
Safe memory handling is crucial for creating robust and reliable C programs. LabEx recommends following these comprehensive strategies.
Memory Allocation Validation
void* safe_memory_allocation(size_t size) {
void *ptr = malloc(size);
if (ptr == NULL) {
fprintf(stderr, "Memory allocation failed\n");
exit(EXIT_FAILURE);
}
return ptr;
}
Memory Management Workflow
graph TD
A[Allocate Memory] --> B[Validate Allocation]
B --> C[Use Memory]
C --> D[Free Memory]
D --> E[Set Pointer to NULL]
Safe Memory Handling Techniques
Technique |
Description |
Implementation |
Null Check |
Validate allocation |
Check malloc() return |
Single Free |
Prevent double-free |
Free once, set NULL |
Size Tracking |
Manage memory bounds |
Store allocation size |
Comprehensive Memory Management Example
#include <stdlib.h>
#include <string.h>
typedef struct {
char* data;
size_t size;
} SafeBuffer;
SafeBuffer* create_safe_buffer(size_t size) {
SafeBuffer* buffer = malloc(sizeof(SafeBuffer));
if (buffer == NULL) {
return NULL;
}
buffer->data = malloc(size);
if (buffer->data == NULL) {
free(buffer);
return NULL;
}
buffer->size = size;
return buffer;
}
void destroy_safe_buffer(SafeBuffer* buffer) {
if (buffer != NULL) {
free(buffer->data);
free(buffer);
}
}
Advanced Memory Management Strategies
Smart Pointer Techniques
#define SAFE_FREE(ptr) do { \
free(ptr); \
ptr = NULL; \
} while(0)
Memory Sanitization
void secure_memory_clear(void* ptr, size_t size) {
if (ptr != NULL) {
memset(ptr, 0, size);
}
}
Error Handling Approaches
- Use errno for detailed error information
- Implement graceful error recovery
- Log allocation failures
- Valgrind for memory leak detection
- AddressSanitizer for runtime checks
- Static code analyzers
Safe Reallocation Pattern
void* safe_realloc(void* ptr, size_t new_size) {
void* new_ptr = realloc(ptr, new_size);
if (new_ptr == NULL) {
free(ptr); // Free original memory on failure
return NULL;
}
return new_ptr;
}
Key Takeaways
- Always validate memory allocations
- Free memory exactly once
- Set pointers to NULL after freeing
- Use memory management tools
- Implement error handling strategies