I've test the program with valgrind, and it gives me 0 memory leak...
running on arduino some thing doesn't seems right...
#include <stdlib.h>
#include <string.h>
#include <WProgram.h>
#include <WConstants.h>
#include <MemoryFree.h>
#include <Wire.h>
#include <WireFacilities.h>
#define LANGUAGE_EEPROM_ADDRESS 80
#define DATA_DONE 14
#define POS_SETUP_DONE 0
#define POS_LANGUAGE_UPLOAD 1
//position array
#define POS_SOCKET_TYPE 1
#define POS_SOCKET_TIMED_TYPE 2
#define POS_SOCKET_PROBED_TYPE 3
#define POS_MEMORY_OPTIONS 4
#define POS_MENU_OPTIONS 5
#define POS_CONTROL_SOCKET 6
#define POS_MANUAL_SET 7
#define POS_DURATION 8
#define POS_CHANGE_SOCKET_OPTIONS 9
#define POS_PROBE_OPTIONS 10
#define POS_SOCKET_OPTIONS 11
#define POS_SETUP_OPTIONS 12
#define POS_SHORT_DAY_OF_WEEK 13
#define POS_DAY_OF_WEEK 14
#define POS_FOR_DATA 92
const char *socketType[] = {"TEMPORIZZATA", "ACCESA", "SPENTA", "SONDATA", NULL};
const char *socketTimedType[] = {"LUCE", "POMPA", "FILTRO", "RISCALDATORE", "RISALITA", "SKIMMER", "VENTOLE", "REFRIGERATORE", "MANGIATOIA", "LUCE LUNARE", "REATTORE", "KALKWASSER", "ELETTROV. REATTORE", "ELETTROV. VASCA", "RABBOCCO VASCA", "RABBOCCO SUMP", "VENT. MOBILE", "LUCE MOBILE", "VENTOLE PLAFO", "ALTRO", "SPENTA", NULL};
const char *socketProbedType[] = {"RISCALDATORE SONDATO", "ELETTR. REATTORE SONDATA", "ELETTR. VASCA SONDATA", "RABB. VASCA SONDATO", "RABB. SUMP SONDATO", "REFRIG. SONDATO", "VENTOLE SONDATE", "LUCE LUNARE SONDATA", "ORP SONDATO", "VENTOLE PLAFO SONDATE", NULL};
const char *memoryOptions[] = {"NON FORMATTARE", "FORMATTA", "ANNULLA", NULL};
const char *menuOptions[] = {"PAUSA PASTO", "PAUSA CAMBIO", "ACCENDI LUCE MOBILE", "ACCENDI LUCI", "AUTO-MANUALE", "GESTIONE SONDE", "GESTIONE PRESE", "IMPOSTAZIONI", "ESCI", NULL};
const char *controlSocket[] = {"AUTO", "MANUALE", "IGNORA", NULL};
const char *manualSet[] = {"ACCESO", "SPENTO", NULL};
const char *duration[] = {"FINO A", "PER", NULL};
const char *changeSocketOptions[] = {"MODIFICA", "IGNORA", NULL};
const char *probeOptions[] = {"MODIFICA SONDE", "REGOLA SONDE", "ANNULLA", NULL};
const char *socketOptions[] = {"INFO. PRESE", "MODIFICA PRESE", "ANNULLA", NULL};
const char *setupOptions[] = {"NUOVO PROGRAMMA", "DATA & ORA", "ANNULLA", NULL};
const char *shortDayOfWeek[] = {"LUN", "MAR", "MER", "GIO", "VEN", "SAB", "DOM", NULL};
const char *dayOfWeek[] = {"LUNEDI'", "MARTEDI'", "MERCOLEDI'", "GIOVEDI'", "VENERDI'", "SABATO", "DOMENICA", NULL};
const char *startingString = "INIZIO CARICAMENTO DATI";
const char *endingString = "FINE CARICAMENTO DATI";
const char *sizeUsed = "SONO STATI USATI ";
/* --------------- DO NOT MODIFIE ---------------------- */
char **list = NULL;
char str[17];
void freeArr(){
byte j = 0;
if(list){
for(; list[j]; j++){
free(list[j]);
list[j] = NULL;
}
free(list);
list = NULL;
Serial.print("Array deleted: free mem = ");
Serial.println(freeMemory());
}
}
int printArr(){
int i = 0;
while(list[i])
Serial.println((char *) list[i++]);
}
int writeString(const char *s, int startPosition, byte maxSize = 15){
byte j = 0;
int pos = startPosition;
while(j < maxSize && s[j])
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, pos++, s[j++]);
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, pos++, '\0');
return pos - startPosition;
}
int writeArr(const char *arr[], int startPosition){
byte i = 0;
int pos = startPosition + 1; //lascio uno spazio per scrivere la lunghezza dell'array (come numero di stringhe)
for(; arr[i]; i++)
pos += writeString(arr[i], pos);
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, startPosition, i);
delay(5);
Serial.print("\t\t:");
Serial.print(pos - startPosition - 1);
Serial.print(", are really: ");
return pos;
}
void writeAddress(int pos, int address){
pos = 2 * pos;
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, pos, (byte) (address >> 8));
delay(5);
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, pos + 1, (byte) (address));
delay(5);
}
int arrStrlen(const char *arr[]){
int len = 0, i = 0;
while(arr[i])
len += strlen(arr[i++]) + 1;
Serial.println(len);
return len;
}
int calculateAddress(byte position){
int pos = 2 * position;
return ((eepromReadData(LANGUAGE_EEPROM_ADDRESS, pos) << 8) | eepromReadData(LANGUAGE_EEPROM_ADDRESS, pos + 1));
}
int loadString(int address, bool isAddress = false){
int pos = isAddress ? address: calculateAddress(address);
for(byte j = 0; (str[j] = eepromReadData(LANGUAGE_EEPROM_ADDRESS, pos++)); j++)
;
return pos - address; // counts even '\0'
}
void loadArr(byte address){
int pos = 0;
byte i = 0, n = 0;
Serial.print("before load array free mem = ");
Serial.println(freeMemory());
pos = calculateAddress(address);
n = eepromReadData(LANGUAGE_EEPROM_ADDRESS, pos++);
list = (char **) calloc(n + 1, sizeof(char *)); // n + 1 because I want list[n] = NULL (made by calloc)
for(; i < n; i++){
pos += loadString(pos, true);
list[i] = strdup(str);
}
Serial.print("Array loaded(");
Serial.print((int) address);
Serial.print("): free mem = ");
Serial.println(freeMemory());
}
void setup(){
int pos = POS_FOR_DATA;
Serial.begin(9600);
Wire.begin();
Serial.println(startingString);
Serial.print("free mem = ");
Serial.println(freeMemory());
eepromWriteData(LANGUAGE_EEPROM_ADDRESS, POS_LANGUAGE_UPLOAD, DATA_DONE);
delay(5);
writeAddress(POS_SOCKET_TYPE, pos);
pos = writeArr(socketType, pos) + 1;
arrStrlen(socketType);
writeAddress(POS_SOCKET_TIMED_TYPE, pos);
pos = writeArr(socketTimedType, pos) + 1;
arrStrlen(socketTimedType);
writeAddress(POS_SOCKET_PROBED_TYPE, pos);
pos = writeArr(socketProbedType, pos) + 1;
arrStrlen(socketProbedType);
writeAddress(POS_MEMORY_OPTIONS, pos);
pos = writeArr(memoryOptions, pos) + 1;
arrStrlen(memoryOptions);
writeAddress(POS_MENU_OPTIONS, pos);
pos = writeArr(menuOptions, pos) + 1;
arrStrlen(menuOptions);
writeAddress(POS_CONTROL_SOCKET, pos);
pos = writeArr(controlSocket, pos) + 1;
arrStrlen(controlSocket);
writeAddress(POS_MANUAL_SET, pos);
pos = writeArr(manualSet, pos) + 1;
arrStrlen(manualSet);
writeAddress(POS_DURATION, pos);
pos = writeArr(duration, pos) + 1;
arrStrlen(duration);
writeAddress(POS_CHANGE_SOCKET_OPTIONS, pos);
pos = writeArr(changeSocketOptions, pos) + 1;
arrStrlen(changeSocketOptions);
writeAddress(POS_PROBE_OPTIONS, pos);
pos = writeArr(probeOptions, pos) + 1;
arrStrlen(probeOptions);
writeAddress(POS_SOCKET_OPTIONS, pos);
pos = writeArr(socketOptions, pos) + 1;
arrStrlen(socketOptions);
writeAddress(POS_SETUP_OPTIONS, pos);
pos = writeArr(setupOptions, pos) + 1;
arrStrlen(setupOptions);
writeAddress(POS_SHORT_DAY_OF_WEEK, pos);
pos = writeArr(shortDayOfWeek, pos) + 1;
arrStrlen(shortDayOfWeek);
writeAddress(POS_DAY_OF_WEEK, pos);
pos = writeArr(dayOfWeek, pos) + 1;
arrStrlen(dayOfWeek);
Serial.println(endingString);
Serial.print(sizeUsed);
Serial.print(pos);
Serial.println(" bytes");
Serial.println("Ora ricarico i dati\n");
loadArr(POS_SOCKET_TYPE);
printArr();
freeArr();
loadArr(POS_SOCKET_TIMED_TYPE);
printArr();
freeArr();
loadArr(POS_SOCKET_PROBED_TYPE);
printArr();
freeArr();
loadArr(POS_MEMORY_OPTIONS);
printArr();
freeArr();
loadArr(POS_MENU_OPTIONS);
printArr();
freeArr();
loadArr(POS_CONTROL_SOCKET);
printArr();
freeArr();
loadArr(POS_MANUAL_SET);
printArr();
freeArr();
loadArr(POS_DURATION);
printArr();
freeArr();
loadArr(POS_CHANGE_SOCKET_OPTIONS);
printArr();
freeArr();
loadArr(POS_PROBE_OPTIONS);
printArr();
freeArr();
loadArr(POS_SOCKET_OPTIONS);
printArr();
freeArr();
loadArr(POS_SETUP_OPTIONS);
printArr();
freeArr();
loadArr(POS_SHORT_DAY_OF_WEEK);
printArr();
freeArr();
loadArr(POS_DAY_OF_WEEK);
printArr();
freeArr();
}
void loop(){
}