Publi

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....

There are 6 comments left Ir a comentario

  1. Pingback: Bitacoras.com /

  2. Fabian /
    Usando Mozilla Firefox Mozilla Firefox 14.0.1 en Ubuntu Linux Ubuntu Linux

    A quien le pide memoria la función malloc? quien es el gestor?

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 13.0.1 en Ubuntu Linux Ubuntu Linux

      Generalmente el responsable de la asignación de memoria es el sistema operativo, pero en este caso, ya que nuestro programa no corre en ningún sistema operativo, la gestión de memoria la hace la propia implementación de las rutinas de asignación y liberación de memoria (malloc(), realloc(), free()). Las variables dinámicas son reservadas en el heap. Al mismo tiempo estas rutinas hacen uso de listas en las que llevan un control de la memoria libre. Para más info entra aquí: http://www.nongnu.org/avr-libc/user-manual/malloc.html

  3. Joao /
    Usando Google Chrome Google Chrome 47.0.2526.106 en Windows Windows 7

    Obrigado…

    1. Gaspar Fernández / Post Author
      Usando Mozilla Firefox Mozilla Firefox 43.0 en Ubuntu Linux Ubuntu Linux

      de nada

  4. samuers /
    Usando Google Chrome Google Chrome 116.0.0.0 en Windows Windows NT

    Buckle up for a retro rollercoaster ride through the frontier! getaway shootout‘s a pixelated posse wranglin’ blast from the past.

Leave a Reply