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() { } |
Pingback: Bitacoras.com /
A quien le pide memoria la función malloc? quien es el gestor?
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
Obrigado…
de nada