
Click the blue text above to follow us
In MCU software development, using pointers can enhance the flexibility and performance of programs, but there are many potential pitfalls, especially in resource-constrained embedded systems.
1
Null Pointer Access
A null pointer does not point to any valid memory address, attempting to access a null pointer can cause the program to crash or exhibit abnormal behavior.
For example, the following erroneous code:
int *ptr = NULL;*ptr = 10; // Null pointer access, may cause crash
Ensure that the pointer is properly initialized before use, and check if the pointer is NULL:
if (ptr != NULL) { *ptr = 10;}
2
Dangling Pointer (Uninitialized Pointer)
An uninitialized pointer points to a random memory address, which may overwrite other important data or lead to unpredictable program behavior.
For example, the following erroneous code:
int *ptr;*ptr = 10; // Dangling pointer access, pointing to unknown memory
Always initialize the pointer when declaring:
int *ptr = NULL;
3
Pointer Out of Bounds
Pointer out of bounds means the pointer exceeds the boundaries of the array or memory block it points to, which can lead to accessing memory areas not belonging to the program, resulting in unpredictable outcomes.
For example, the following erroneous code:
int arr[5] = {1, 2, 3, 4, 5};int *ptr = arr;ptr += 6; // Out of array bounds*ptr = 10; // May cause crash
Ensure pointer operations do not exceed valid memory ranges. You can control pointer movement using the array size:
for (int i = 0; i < 5; i++) { *(ptr + i) = i;}
4
Memory Leak
Forgetting to free memory when using dynamic memory allocation can lead to memory leaks, which is particularly critical in MCU development due to the limited memory resources of embedded systems.
For example, the following erroneous code:
int *ptr = (int *)malloc(10 * sizeof(int)); // No release of allocated memory
After using dynamically allocated memory, it should be freed in a timely manner:
free(ptr);ptr = NULL; // Set pointer to NULL after freeing to avoid dangling pointer
5
Dangling Pointer
A dangling pointer points to released memory. Even if the memory has been freed, the pointer still holds that address, but this address may have been reassigned to other variables or programs.
For example, the following erroneous code:
int *ptr = (int *)malloc(10 * sizeof(int));free(ptr); // Free memory*ptr = 10; // Dangling pointer access, may cause crash
Set the pointer to NULL after releasing memory to avoid using a dangling pointer:
free(ptr);ptr = NULL;
6
Pointer Type Mismatch
When performing pointer type conversion or operations, if the types do not match, it may lead to incorrect data interpretation, especially when accessing peripheral registers or hardware addresses.
For example, the following erroneous code:
char *ptr = (char *)malloc(sizeof(int));*ptr = 0xFF; // Modifying 4-byte int, only changed 1 byte
Ensure that the pointer type matches the data type being operated on, especially pay attention to alignment issues when accessing registers:
int *ptr = (int *)malloc(sizeof(int));*ptr = 0xFFFFFFFF; // Ensure type match
7
Pointer Access in Multitasking Environment
In RTOS or multitasking systems, sharing the same pointer between different tasks may lead to race conditions or data consistency issues, especially when one task modifies the memory pointed to by the pointer while another task is also accessing it.
For example, the following erroneous code:
int *shared_ptr;// Task 1 modifies*shared_ptr = 10;// Task 2 accesses simultaneouslyint val = *shared_ptr; // Data inconsistency
In a multitasking environment, use mutexes or semaphores to protect shared pointers:
// Task 1osMutexWait(mutex_id, osWaitForever);*shared_ptr = 10;osMutexRelease(mutex_id);// Task 2osMutexWait(mutex_id, osWaitForever);int val = *shared_ptr;osMutexRelease(mutex_id);
8
Alignment Issues
In MCUs, certain processors require data accesses to be aligned to specific byte boundaries. If unaligned pointers are used to access memory, it may lead to bus errors or lower data access efficiency.
For example, the following erroneous code:
char data[10];int *ptr = (int *)&data[1]; // May not be aligned to 4 bytes*ptr = 0x12345678; // Causes access error
Ensure that the data address accessed by the pointer is aligned according to the processor’s requirements:
int *ptr = (int *)((uintptr_t)(data + 3) & ~0x3); // Force alignment
Using pointers in MCU development requires extra caution, especially in memory-limited and resource-constrained situations.
By adopting good coding practices (such as initializing pointers, checking for NULL, and using mutexes to protect shared data, etc.), most pointer-related issues can be avoided.
