Poesía Binaria

Memoria dinámica con Arduino en C++

Uno de los problemas al programar en C++ con Arduino es la utilización de memoria dinámica. Podemos comprobar que el uso de malloc / realloc / free está soportado, pero no new y delete.

La ventaja, en Arduino, para utilizar new y delete es que éstos llaman al constructor y al destructor respectivamente, lo cual nos permite poder crear objetos de forma dinámica.

Para crear los operadores new y delete, he utilizado malloc() y free(), lo malo es que no hacemos comprobación de errores, por lo que, cuando falle algo, los resultados serán inesperados, aunque podremos crear alguna función que detenga la ejecución del programa cuando ocurra algún error.

Dejo tres ficheros, dos pertenecen a la biblioteca dynmem, y otro será el programa de ejemplo (dynres.pde):

dynmem.h:

1
2
3
4
5
6
7
8
9
10
11
/* Con estos operadores podremos hacer reserva dinámica de variables,
 objetos y arrays al estilo C++ */

#ifndef DYNMEN_H
#define DYNMEN_H

void * operator new(size_t size);
void * operator new[](size_t size);
void operator delete(void * ptr);
void operator delete[](void * ptr);

#endif

dynmem.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <stdlib.h>     // Para malloc() y free()
#include "dynmem.h"

// No tenemos excepciones, no hacemos comprobación de errores, aunque podemos
// hacer una función de error que bloquee el Arduino cuando ocurra algo y llamarla
// desde aquí si ocurre algo...
// La ventaja de usar un operador new frente a malloc() es que el operador
// llamará al constructor del objeto que vamos a crear...
void * operator new(size_t size)
{
  void *p;
  p=(void*)malloc(size);

  // if (!p)
  //   error();

  return p;
}
// lo mismo ocurre con delete, con este, llamamos al destructor del objeto.
void operator delete(void * ptr)
{
  if (ptr)
    free(ptr);
}

void * operator new[](size_t size)
{
  void *p;
  p=(void*)malloc(size);

  // if (!p)
  //   error();

  return p;
}

void operator delete[](void * ptr)
{
  if (ptr)
    free(ptr);
}

dynresv.pde:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <dynmem.h>

class MiClase
{
public:
  ~MiClase();
  MiClase();
};

MiClase::~MiClase()
{
  Serial.println("Objeto destruido");
}

MiClase::MiClase()
{
  Serial.println("Objeto construido");
}

MiClase *objet;

void setup()
{
  Serial.begin(9600);
  objet=new MiClase[10];
  Serial.println(sizeof(*objet));
  delete [] objet;
}

void loop()
{

}

También podría interesarte....