Limitazioni compilatore

no, a scuola ho studiato il C, non il C++. poi sul C++ me la cavo perchè unisco le conoscenze di C e di java :slight_smile:

Tu mi stai quindi dicendo che quando ad un array cerco di aggiungere un elemento, il compilatore prende e copia tutto l'array da un'altra parte se non può aggiungere l'elemento nello spazio occupato prima dall'array. Vedi che allora è come dico io, che alla fine non conviene gestire la memoria così?

non lo fa il compilatore. se tu crei un array di 100 elementi, tutta la ram necessaria viene occupata subito.

Se tu avessi un array di 100 elementi, poi aggiungi 1 variabile a caso, dopodiché vuoi aggiungere 1 elemento all'array, questo non ci starebbe e tutto l'array verrebbe copiato dopo la variabile che rompe le scatole nel mezzo.

esatto

In questo modo perdo 100 byte di memoria in un colpo.

non perdi la memoria, puoi usarla per altro.

Se poi tale memoria non la riadopero per altre cose, l'aggiunta di 1 solo elemento all'array è divenuta un'operazione altamente sconventiente.

per questo sono nate le liste. Aggiungerei anche il fatto che nel momento della copia, hai un array di 100 e uno di 101, quindi è molto facile che finisci la ram quando invece ne avresti ancora un pò da usare..

pensa alle stringhe, se non fossero array dinamici che casino sarebbero da usare

lesto:
pensa alle stringhe, se non fossero array dinamici che casino sarebbero da usare

Le stringhe con l'oggetto String. Però le stringhe char* sono statiche, quindi non ho di questi problemi.

se devi concatenare le 2 stringhe il problema si ripresenta

lesto:
se devi concatenare le 2 stringhe il problema si ripresenta

+1

Avrei una domanda visto che parlavate qui di array dinamici...

ho una funzione sul mio arduino Yun:

Process uptime;
uptime.runShellCommand("cat /proc/uptime | cut -d. -f1");
while (uptime.available() > 0) {
    c = uptime.read();
    Serial.write(c);
}

Non riuscendo a compiere operazioni matematiche sul numero che ottenevo e che visualizzavo correttamente sul monitor seriale, all'inizio credevo fosse un problema del tipo di variabile (c come char, int, long...?) poi un utente mi ha illuminato facendomi notare che il "numero" che veniva memorizzato tramite la funzione veniva letto"carattere a carattere" e che quindi avrei dovuto trattarlo come un ARRAY da trasformarmi poi in un INT o LONG che sia...

Il nuovo problema è quindi, visto che il comando in linux mi restituisce il numero di secondi trascorsi dall'avvio della scheda, e che questo numero sarà composto sempre da più cifre... se dichiaro un array per leggere l'output, come faccio che devo dichiarare anche quanti caratteri deve avere l'array ? mi serve una sorta di array dimensionato ad ogni loop in base al numero di cifre che compongono i secondi restituiti da linux... E' una cosa possibile ?
Ci sono altri modi altrimenti per aggirare il problema ?

Secondo me è un problema secondario, quando hai dichiarato un array di 20 caratteri sei a posto. Con 20 cifre conti migliaia di anni :wink:

Oh..perdona la mia ignoranza ma credevo che non potevo dichiararlo più grande a monte in quanto poi avrei avuto problemi a leggerne i valori...

cmq dicendo che una unsigned long è composta da 10 cifre, non mi conviene limitare l'array a [10] ?

Se usi un array di char, considera una cella in più per il carattere terminatore (\0). Quindi 11 elementi.

mmm visto che l'index di un array inizia da 0 non è giusto mettere 10 e avrò lo stesso 11 valori "disponibili" ?

No, perché l indice inizia da zero, mentre la dichiarazione della dimensione inizia da 1

se fai un array di 10 celle, la prima cella avrà indice 0, ma l'ultima sarà la 9!

infatti il for si fa con il <, e non con il <=, esempio:

const sizeArray = 10;
char array[sizeArray];
for (int i=0; i < sizeArray ; i++){
 //i da 0 a 9!
}

ma trovo INUTILE che tu passi da array di caratteri! puoi fare la confersione della cifra al volo, moltiplichi il totale per 10 (inizializzato a 0, quindi la prima volta resta 0), sommi al totale la cifra

unsigned long uptime = 0; //UNSIGNED! è importante!
Process uptime;
uptime.runShellCommand("cat /proc/uptime | cut -d. -f1");
while (uptime.available() > 0) {
    c = uptime.read();
    uptime *= 10;
    uptime += c - '0'; //il carattere C non corrisponde al numero, ma al corrrispondente in tabella ascii (che è cifra+48). però '0' viene interpretato dal compilatore come "carattere 0" e viene quindi sostituito con 48. Essendo tutti i numeri successivi ('1' = 49, '2' = 50 etc.. vedi tabella ascii)la coversione è sempre valida.
}

e la variabile "c" in questo caso è una CHAR ?

sì, ed un char in realtà è un byte, in cui il valore numerico è mappato al simbolo "umano" usando la tabella ascii

ok sto caricando lo sketch con le tue indicazioni..
p.s. se chiamo la variabile "uptime" come il processo mi da errore..

  Process uptime;
  uptime.runShellCommand("cat /proc/uptime | cut -d. -f1");
  unsigned long sec = 0;
  while (uptime.available() > 0) {
    char c = uptime.read();
    sec *= 10;
    sec += c - '0';
   }
  Serial.flush();
  Serial.write(sec);

l'output restituito sono caratteri strani/quadratini illeggibili :frowning:

se chiamo la variabile "uptime" come il processo mi da errore..

certo, non puoi avere collisione di nomi di variabili/oggetti con lo stesso nome, colpa mia

l'output restituito sono caratteri strani/quadratini illeggibili smiley-sad

stai usando la write() che scrive il valore binario (quindi il valore dei 4 byte), devi usare la print che converte il tuo long in un bellissimo array di char adatto agli umani :stuck_out_tongue:

ok.. ho cambiato write in print e ora ho un output più leggibile:

1082192108220210822121082222

il 2 che viene riportato a fine di ogni loop di lettura cos'è ? il carattere di chiusura del CHAR ?

devo mettere qualcosa tipo:

if (c != '\n')  ?

no, in teoria hai solo il numero, usa un println() per andare a capi in automatico ad ogni output.
OPPURE può essere che stai leggendo anche un carattere non numeriuco, come uno spazio o un a capo. effettua le operazioni di moltiplicazione e somma solo se il carattere letto è '0' <= c <= '9'

if (c >= '0' && c <='9'){
   //carateerere numerico
}else{
   //carattere invalido
}

Pensando proprio ad un carattere vuoto al termine ho scritto così:

void loop() {
  Process uptime;
  uptime.runShellCommand("cat /proc/uptime | cut -d. -f1");
  unsigned long sec = 0;
  while (uptime.available() > 0) {
    char c = uptime.read();
    if (c != '\n') {
      sec *= 10;
      sec += c - '0';
    }
  }
  Serial.flush();
  //Serial.print(sec);
  int d = sec / 86400;
  sec -= d * 86400;
  int h = sec / 3600;
  sec -= h * 3600;
  int m = sec / 60;
  sec -= m * 60;
  lcd.setCursor(0, 0);
  lcd.print("Uptime:");
  lcd.setCursor(0, 1);
  lcd.print(d);
  lcd.print("d ");
  if (h < 10) lcd.print("0");
  lcd.print(h);
  lcd.print("h ");
  if (m < 10) lcd.print("0");
  lcd.print(m);
  lcd.print("m ");
  if (sec < 10) lcd.print("0");
  lcd.print(sec);
  lcd.print("s");
  delay(500);
}

5a2v0 ... stai facendo cross-posting (ne stai parlando anche QUI) il che è contrario al regolamento !

Decidi dove vuoi parlarne e non scrivere su più thread !!!

Guglielmo

Perdonatemi... Qui avevo iniziato a chiedere solo x la storia dell' array dinamico... Poi sono andato fuori topic... Scusate ancora e grazie per i preziosi aiuti