▷ Pointers in Arduino: Mastering Memory Management

Pointers are one of the most powerful tools in Arduino programming, but also one of the most feared. In this comprehensive guide, we will demystify pointers and you will learn how to use them to optimize memory usage and create more efficient programs.

What are Pointers?

A pointer is a variable that stores the memory address of another variable. Instead of containing a value directly, it contains the location where that value is stored.

Basic Concept: Variables vs Pointers

int value = 42; // Normal variable that contains the value 42
int *ptr = &value; // Pointer that contains the memory address of 'value'

Serial.println(value); // Output: 42
Serial.println(*ptr); // Output: 42 (accessing the pointed value)
Serial.println((int)ptr); // Output: memory address (e.g.: 2236)

Why use Pointers in Arduino

  • Memory savings:Manipulating addresses instead of copying large data
  • Pass by reference:Modify variables in functions without making copies
  • Array handling:Efficient access to array elements
  • Dynamic memory:Allocate and free memory as needed
  • Complex structures:Create data structures like linked lists

Basic Pointer Syntax

Operator Meaning Example
* Declare pointer or dereference int *ptr; or *ptr = 5;
& Address of a variable ptr = &variable;
-> Accessing members of structures ptr->miembro = 10;

Pointers and Arrays

Pointers and arrays are closely related in C++. An array can be treated as a pointer to its first element.

Example: Traversing an Array with Pointers

int values[] = { 10, 20, 30, 40, 50 };
int *ptr = values; // ptr points to the first element of the array

for (int i = 0; i < 5; i++) {
  Serial.println(*ptr); // Access the current value
ptr++; // Move to the next element
}
💡 Important Note: When you increment a pointer (ptr++), you actually move the size of the data type. For an int, you will move 2 bytes in most Arduinos.

Pointers in Functions

Passing variables by reference using pointers allows you to modify the original values directly.

Example: Modifying Variables with Pointers

// Function that modifies the original value through a pointer
void duplicate(int *valuePtr) {
*valuePtr = *valuePtr * 2; // Modifies the original value
}

void setup() {
  Serial.begin(9600);
  int number = 5;

  Serial.print("Original: ");
  Serial.println(number); // Output: 5

  duplicate(&number); // Passes the address of 'number'

  Serial.print("Duplicated: ");
  Serial.println(number); // Output: 10
}

Pointers and Dynamic Memory

In Arduino, dynamic memory is limited, but pointers allow efficient management of it.

Example: Use of malloc() and free()

void setup() {
  Serial.begin(9600);

// Reserve memory for 10 integers
  int *numbers = (int *)malloc(10 * sizeof(int));

  if (numbers == NULL) {
    Serial.println("Error allocating memory!");
    return;
  }

// Fill the array with values
  for (inti = 0; i < 10; i++) {
    numbers[i] = i * 10;
  }

// Use the values...
  for (inti = 0; i < 10; i++) {
    Serial.println(numbers[i]);
  }

// Free the memory when it is no longer needed
  free(numbers);
}

⚠️ Caution!Always check that the dynamic memory allocation was successful (not NULL) and free the memory with free() when you no longer need it to avoid memory leaks.

Pointers to Structures

Pointers are especially useful for working with complex data structures.

Example: Pointers with Struct

// Define a structure to represent a sensor
struct Sensor {
  int pin;
  float value;
  unsigned long lastReading;
};

void readSensor(struct Sensor *s) {
  s->value = analogRead(s->pin) * (5.0 / 1023.0);
  s->lastReading = millis();
}

void setup() {
  Serial.begin(9600);

// Create an instance of Sensor
  struct Sensor mySensor;
  mySensor.pin = A0;

// Read the sensor using a pointer
  readSensor(&mySensor);

  Serial.print("Value: ");
  Serial.println(mySensor.value);
}

Common Errors with Pointers

  • Uninitialized pointers: Always initialize pointers to NULL or to a valid address
  • Dereferencing NULL pointers: Causes crashes or unpredictable behavior
  • Memory leaks: Allocating memory with malloc() and not freeing it with free()
  • Out of bounds access:Accessing unallocated memory through the pointer
  • Dangling pointers:Using pointers that point to already freed memory

Conclusion

Pointers are a powerful tool in Arduino programming that, when used correctly, can significantly improve efficiency and control over the microcontroller's resources. Although they have a learning curve, mastering pointers will allow you to write more optimized and professional code.

Start with simple examples and gradually move on to more complex uses. Always check your code carefully and pay attention to memory management to avoid common mistakes.

0/Leave a comment/Comments

Hello! We're so glad you've made it this far and are reading this article on Edeptec.

This form is an open space for you: you can leave a comment with your questions, suggestions, experiences, or simply your opinion on the topic discussed.

» Did you find the information helpful?
» Do you have any personal experiences you'd like to share?
» Do you have any topics you'd like to see covered in future articles?

Remember that this space is for learning and sharing, so we encourage you to participate respectfully and constructively. Your comments can help other readers who are on the same path, whether in electronics, programming, sports, or technology.

Thank you for being part of this learning community! Your participation is what makes this project grow.