Ridimensionare array

Avrei bisogno di cambiare la dimensione di un array in esecuzione.

Esempio:

byte mioarray[35]:

mioArray ha 35 elementi.

Come posso cambiare dimensione esempio in 20 elementi
e poi in altre dimensione?

Carletto.

se non sai cos'è un puntatore lascia stare :grin:
altrimenti studiati i puntatori e la realloc. Non tentare di usare la realloc() senza conoscere i puntatori che sicuro fai solo casino. Tanto casino.

lesto:
se non sai cos'è un puntatore lascia stare :grin:
altrimenti studiati i puntatori e la realloc. Non tentare di usare la realloc() senza conoscere i puntatori che sicuro fai solo casino. Tanto casino.

Uso i puntatori anche se non ho molta dimestichezza. Se posso fare altrimenti li evito.

Ho chiesto in lista perchè nel reference di Arduino non ho trovato nulla a riguardo.

Carletto

allora devi guardare come si usa free(), malloc() e realloc(), e occhio a non creare garbage.
E gli array SONO puntatori (sotto mentite spoglie), quindi no, non esiste un modo per farne a meno.

Cerca con Google: array dinamico c

Potresti variare la sua dimensione se l'array lo dichiari all'interno della funzione e non pubblico

void funzione_A(){
byte mioarray[35]; qui mi bastano 35
}

void funzione_B(){
byte mioarray[15]; qui mi bastano 15
}

quando esci dalle funzioni quello spazio che hai occupato dentro la func viene riutilizzato per altro

Però mi interesserebbe approfondire il discorso malloc() e realloc()

Se io ho nello sketch
PROGMEM prog_uint16_t charSet = { 65, 32, 16, 10, 11};
si potrebbe modificare il contenuto di quell' array durante l'esecuzione del programma o almeno una sola volta nel setup per esempio?
Se io potessi prendere 20kb della flash e scriverla attraverso la lettura di un file su sd oltre ai 4 della eeprom sarebbe la soluzione a un sacco di problemi varrebbe per me la pena di starci su anche 2-3 mesi :cold_sweat:
Sarebbe la stessa cosa che riscrivere lo sketch da remoto?

ciao

prova ma dubito, per il fatto che è PROGMEM.

per la eeprom il discorse è differente, salvi nella cella 0 e 1 il numero di elementi e poi crei un array di quelle dimensioni del tipo di dato che ti interessa e poi fai un puntatore a byte che punta all’indirizzo dell’array dichiarato, e ogni byte letto dalla eeeprom finisce nel puntatore byte, il quale poi incrementerà il suo indirizzo di 1, il tutto finchè indirizzo di partenza < indirizzo di partenza + sizeof(tipo di dato salvato)*numero elementi

Per la eeprom già la uso e sono a tappo :), quali argomenti dovrei studiare per manipolare la flash? ovviamente parlo di arduino

grazie ciao

pablos:
Se io ho nello sketch
PROGMEM prog_uint16_t charSet = { 65, 32, 16, 10, 11};
si potrebbe modificare il contenuto di quell' array durante l'esecuzione del programma o almeno una sola volta nel setup per esempio?

Certo che puoi farlo, i 328 permettono di scrivere la flash da programma previa allocazione dello spazio da utilizzare.
Leggi qui e avrai la soluzione alla tua domanda.

astrobeed:
previa allocazione dello spazio da utilizzare.

quindi lo spazio allocato non è dinamico ma fissato a tempo compilazione?

lesto:
quindi lo spazio allocato non è dinamico ma fissato a tempo compilazione?

La flash per forza di cose visto che normalmente ospita solo il programma, se non riservi prima lo spazio per le eventuali variabili poi c'è il reale rischio di andare a scrivere sul programma stesso.

infatti quello che immaginavo, magari esiste qualcosa per risalire alla flash utilizzabile ed auto allocarla come array di byte, così con un pò di magia dei puntatori si può usare tutta.. ma è roba assai complessa.

Certo immaginavo che era come giocare al piccolo chirurgo, devo stare attento a rimenere nei limiti della Flash usata e fuori dalla Sram delle variabili, anche se la sram dovrebbe essere al di fuori dei 256k in un altra casa :slight_smile:

Flash Memory 256 KB of which 8 KB used by bootloader
SRAM 8 KB
chissà quegli 8 kb dei bootlooader.... saranno all'inizio o in fondo? :slight_smile:

c'è il reale rischio di andare a scrivere sul programma stesso.

Bhe si finchè scrivo sul programma, si schianta, ma resettando risolvo, ma se scrivo nel bootloader sono guai seri.

Però di solito la cella di memoria vuota restituisce in decimale il byte 255, in qualche modo dovrei riuscire a vedere quali celle sono impegnate.

Bho... io ci voglio provare è una cosa più grande di me :smiley: :smiley:

Grazie astro interessante quel link, forse fa al caso mio

Però di solito la cella di memoria vuota restituisce in decimale il byte 255, in qualche modo dovrei riuscire a vedere quali celle sono impegnate.

da quando questo? a me non risulta, anzi ci sarà dentro l'ultimo valore memorizzato... esattamente come in una variabile non inizializzata!

lòa parte boot-loader CREDO sia protetta, ma magari mi sbaglio. mi pare che il bootloader sia più in fondo, poi schiacciato sul fondo il programma, poi schiacciati all'inizio i vettori di interrupt... ma non sono assolutamente sicuro, anzi! forse astro lo sà, altrimenti guardando vecchie discussioni si è parlato relativamente spesso di queste cose

da quando questo? a me non risulta, anzi ci sarà dentro l'ultimo valore memorizzato

Sì certo, anche tu hai ragione, ma non avendo scritto programmi più lunghi di 58k dovrò trovare delle celle vergini, almeno che per un pezzo siano tutte uguali :slight_smile: quello dovrebbe farti capire che da un certo punto in poi non c'è mai stato nessuno :slight_smile:

la program memory parte da 0x0000

@pablos:
il bootloader occupa sempre la parte più alta della memoria Flash.

@lesto:
una cella FLASH o EEPROM erasata contiene $FF come valore "vuoto".

Ho letto un testo di Banzi dove uno schema a blocchi mette memory program 0x0000 e il boot lo mette in fondo comunque fa lo stesso a me serve il centro ahahahahah.

@Astro il link che hai messo avr-libc: Data in Program Space mi scrive dei byte prestabiliti usando uno spazio della flash,
vedo solo dei pgm_read, ma non dei pgm_write
io chiedo di poter scrivere su una cella della flash come faccio con la eeprom a prescindere che rischio di andare sopra allo sketck , che istruzioni devo usare per leggere e scrivere su una posizione?

grazie ciao

Se tu avessi un vettore v1 di dimensione x e vorresti avere un vettore v2 di dimensione y allora devi chiamare la funzione che ho scritto come nel seguente modo:

int * v2 = changeDim(v1, y);

A questo punto v2 contiene l’indirizzo a partire dal quale è memorizzato l’array in memoria.

int* changeDim(int* vector, int newDim){
    if (vector != 0 ){
        int* newArray = new int[newDim];
        int vectorLen = newDim;
        for (int var = 0; var < vectorLen; ++var)
            newArray[var] = vector[var];

        return newArray;
    }
    else
        return (int*)0;
}

La mia funzione restituisce vettore di iteri ma basta cambiare il tipo per ottenere un vettore di diverso tipo.

ci sono 3 errori:

  1. stai creando garbage non distruggendo il vecchio vettore (il c++ non ha un garbage collector come java o simili, la spazzatura la si porta fuori a manina)
  2. alla funziona non puoi passare un array, poichè un array ha indirizzo costante, e quindi non modificabile tramite malloc o new
  3. dai per scontato che la “new” abbia successo, cosa non vera. se non c’è ram disponibile la new/malloc ritorna NULL

ci sono anche 3 imprecisazioni secondo me:

  1. stai confondendo new (usato per le classi) con malloc e compagnia bella (la new in realtà poi chiama la malloc, ma il punto è che confondi C e C++ inutilmente)
  2. prima di fare una malloc prova a fare una realloc: questa non solo POTREBBE (non ne sono sicuro) funzionare anche con gli array, visto che non modifica la posizione dell’array ma cerca solo di espanderlo, ma appunto per questo comportamento non è necessario copiare il contenuto del vecchio vettore in quello nuovo risparmiando un sacco di cicli macchina, senza contre che nella fase di copia evita di occupare quasi il doppio di RAM necessaria dal tuo metodo (vecchio vettore + nuovo vettore).
    lo svataggio della realloc() è che spesso fallisce perchè subito dopo l’array la RAM è già usata da altre variabili… in tal caso si fa il fall-back a malloc
return (int*)0;

è illeggibile, non sono neanche sicuro di interpretarla bene. forse intendevi

return null;