Problema dichiarazione Variabili Globali/Locali nel progetto e nelle Librerie

Salve a tutti,

ho due problemi legati alla dichiarazione delle variabili globali e locali che spiegherò in modo separato perchè uno è implementato in un normale progetto e l'altro all'interno della libreria.

PROBLEMA: Dichiarazione variabile locale una sola volta in una funzione (Void o Restituente)

Ho già trovato un post dove si citava tale argomento ed è uscito fuori l'istruzione "static" e pensavo mi avesse risolto il problema ma invece no.

Il problema noto, che alla fine dei conti è lo stesso per le dichiarazioni di variabili nelle librerie,
sono le VARIABILI IN ARRAY dove l'indice se non è costante ma modificabile tramite parametri mi genera errori di compilazione.

Per rendere le cose ancora più capibili scrivo un esempio:


void Funzione_1(byte Valore, byte Numero_Valori, byte Indice){

byte Valori[Numero_Valori];

Valori[Indice] = Valore;

Serial.write(Valori[Indice]);

}


PS: mi scuso dell'inutilità di tale funzione ma è a solo scopo dimostrativo.

Nella funzione soprastante essa genera un'array di byte tanti quanti impostati da un parametro che è sulla funzione stessa e poi si passa alla parte di codice funzionale dove l'array in base all'indice riceve il dato in ingresso che poi a sua volta viene inviato tramite seriale.

Il PROBLEMA sta nel fatto che la riga di codice "byte Valori[Numero_Valori];" viene eseguita ogni volta che viene richiamata la funzione e io desidero dichiararla una sola volta all'interno di quel blocco.

L'utilità che desidero sta nel fatto di poter usare funzioni come questa, senza dover dichiarare variabili globali specifiche in altri progetti ma semplicemente copiando ed incollando ed modificando i parametri in ingresso senza dovermi preoccuparmi del codice interno con l'IMPORTANZA che nel blocco le variabili dichiarate non perdano il loro valore perchè ho creato funzioni dove se la variabile funge da contatore deve memorizzare il valore sempre anche dopo molti richiami tenendo sempre conto che si trattino di array poichè se fosse una sola variabile potrei usare la funzione "static" ma con l'array modificabile da parametro non me lo compila.

Infine questo dubbio va anche nella creazione di librerie dove non trovo un modo di rendere un'array interno con l'indice modificabile dall'utente.

Ho cercato di capire bene la libreria dello ShiftRegister 74HC595 dove imposti il numero di integrati ed in automatico vengono generate il giusto numero di variabili richieste.
All'interno di tale libreria ho trovato la funzione "memset()", "sizeoff()" e "malloc()" e dai commenti è come se fossero tali istruzioni a generare la quantità di variabili voluta.

Allego il progetto dove viene usata la libreria per il 74hC595 così potete dare un'occhiata.

Spero che esista un modo per far si da generare la dimensione di un array all'interno di una libreria e dichiarare variabili locali una sola volta all'interno di funzioni (sempre con array).

PS: l'istruzione "static" l'ho già provata e non funziona con array ad indici dinamici modificabili, per lei deve essere tutto costante a meno che non esista un metodo apposito.

SCSR74HC595.zip (2.36 KB)

Controlla su un buon libro di 'c',
Comunque malloc riserva uno spazio di memoria
La dimensione la devi calcolare tu, casomai con sizeof
La malloc restituisce un puntatore a void
Che tu casterai a puntatore al tipo che ti Serve
il puntatore così ottenuto lo potrai restituire e usare come un nuovo array
Ma tutto questo è 'male' su un Arduino, non ha abbastanza 'muscoli' per gestire questa cosa senza problemi
Giusto per cronaca questa cosa si chiama 'allocazione dinamica della memoria'
Se non sei esperto (ma molto) in 'C', lasciala stare....

Penso che quello che vorresti fare sia sbagliato come modo di operare!
Una funzione fa qualcosa in base ai argomenti che riceve
Una funzione che esegue un compito e che sia riutilizzabile, riceverà un array come parametro e lavorerà su quello. L'array inviato non deve necessariamente essere dichiarato globalmente, potrebbe essere locale a una funzione e inviato a un altra.

void miaFunzione(){

    int ArrayLocale[5];

    funzioneGestioneArray(ArrayLocale);

}


void funzioneGestioneArray(int* A){

      A[1]=valore;

 }

Non hai torto,
In effetti se il problema è di dichiarare un array di dimensione conosciuta a runtime e non a compiletime basta dichiararlo locale alla loop e non uscire mai dalla prima chiamata della loop
Una cosa del genere

char * questa;
//variabile puntatore dichiarata ma non inizializzata
.
.
setup()
.
.



loop()
{
   while(1)
   {
      char * quella[analogRead(A0)];
      // che è Chiaramente un VLA
E non uscendo mai dalla prima chiamata della loop non "Muore" mai
Il problema è renderlo globale

questa=quella;

//adesso il puntatore "questa"
Che è globale
Si può usare come se fosse
L'array "quella" che è invece locale
Ma non muore mai come se fosse globale

// qui ci mettiamo tutto il resto della loop

   }
}

per lo OP invece:
Urge che tu metta i tag code
Te pensa che io li ho usati pur se da furbofono...

A livello teorico avere uno o più array non globali di dimensione modificabile dall'utente é possibile. Tutto gioca sul fatto che alla fine di una funzione lonspazio occupato dalle sue variabili é solo dichiarato libero, ma NON liberato. Gli array a dimensione modificabile sono quindi possibili in questo modo:

  1. li crei come array normali in una funzione apposta, che conosce le loro lunghezze (e questo lo puoi fare senza problemi)
  2. la funzione fa cose (riempirli, leggerli, altro...) e poi termina restituendo il puntatore al primo elento del primo array
    3)salvi quel puntatore innuna variabile globale apposita, che può essere usato come array (ma NON é un array, lo spazio che occupa é considerato LIBERO)
  3. da quando esci dalla funzione in poi non deve più essere dichiarata NESSUNA variabile, ne da te ne da altre funzioni. Esse amdrebbero infatti a scriversi al posto del contenuto di quegli array (puoi usare tranquillamente variabili già dichiarate).
  4. richiami la funzione tutte le volte che vuoi per modificare il contenuto e la dimensione degli array

Per evitare restrizioni così assolute puoi dichiarare nella funzione creatrice un array di lunghezza che si ritiene sufficiente PRIMA degli altri senza usarlo. Quello spazio sarà utilizzabile per altre variabili locali, una volta usciti dalla funzione.
Come hai capito tutto questo ha il grande difetto dell'estrema fragilità, ma é così che farei una cosa che non si può fare (a meno di non essere dei geni di programmazione sadici)

Ma almeno qualcuno conosce un codice da implementare in una libreria dove per esempio la variabile
"DATA[]" ha l'indice modificabile all'uscita nella istanza ?

ES:

#include "FLIPFLOP.h"

FLIPFLOP FF_1(NumOuts, Data, Clock);

Dove il parametro "NumOuts" fa a definire l'array interno.

Esiste un metodo o no ? Ci sono esempi ?
Qualcuno sa come fare o è una cosa COMPLICATISSIMA che solo a me mi serve ?

Penso sia uno dei quesiti più difficili ma altrettanto efficienti.

Grazie per l'eventuale aiuto...

Ma tu hai letto le mie risposte?

MizzardNet:
Dove il parametro "NumOuts" fa a definire l'array interno.

Perdonami, ma "interno" rispetto a cosa?

Se intendi dichiarare un array "interno" ad una funzione e aspettarti che mantenga lo stato anche fuori, devi cambiare la logica perchè questo non accadrà mai, una volta usciti dal blocco le variabili dichiarate in esso non sono più referenziabili a meno di non usare i trucchi che ti hanno già indicato (appoggi il riferimento su un alias globlale o con scope più ampio e poi lo vai a riprendere, etc..)

Oppure cambi la logica, la funzione può diventare un metodo di classe, all'interno della quale c'è un membro privato che è l'array, in questo modo l'array resta nascosto ma mantiene lo stato all'uscita dal metodo

Una cosa così:

#include <Arduino.h>

class MyDumbArrayOfBytes
{
private:
    byte* internalArray;
    int size;

public:
    MyDumbArrayOfBytes(int _size);
    ~MyDumbArrayOfBytes();

    void Set(int _index, byte _value);
    byte Get(int _index);
    int Size();
};

MyDumbArrayOfBytes::MyDumbArrayOfBytes(int _size)
{
    internalArray = new byte[_size];
    size = _size;
}

MyDumbArrayOfBytes::~MyDumbArrayOfBytes()
{ }

void MyDumbArrayOfBytes::Set(int _index, byte _value)
{
    internalArray[_index] = _value;
}

byte MyDumbArrayOfBytes::Get(int _index)
{
    return internalArray[_index];
}

int MyDumbArrayOfBytes::Size()
{
    return size;
}

Che si può usare così:

#include <Arduino.h>
#include <MyDumbArrayOfBytes.h>

void setup()
{
  Serial.begin(9600);

  MyDumbArrayOfBytes mdaob(analogRead(A0));

  Serial.println(mdaob.Size());
  for (int i = 0; i < mdaob.Size(); i++)
  {
    Serial.println(mdaob.Get(i));
  }
}

Per adattarlo alle tue necessità devi effettuare una scelta, o separi il metodo che alloca l'array da quello che lo utilizza e in questo caso la classe va più o meno bene così, oppure se vuoi mantenere la logica attuale devi dotarti di flagettino che setti a true alla prima inizializzazione e lo testi sulle successive in modo da non ripetere l'allocazione dell'array.

Ciao

Tu saresti (leggo dalla tua presentazione) un po' arrugginito?
Quando riprenderai appieno cosa farai?
Riscriverai lo IDE per farlo girare su una MEGA?

Sia chiaro: il mio è un complimento, un grosso complimento

Comunque non capisco il bisogno di avere array di lunghezza variabile ma i cui valori si mantengano. Sapendo che tu scrivi il programma la successione degli eventi é questa:
0) ti serve un array per delle ragioni (farci cose)

  1. lo crei
  2. lo riempi
  3. ci fai cose
  4. l'array non ti é più necessario, quindi perché tenerlo?
  5. torna a 0

E se la successione é questa non ci sono problemi, basta creare un normale array in una funzione e usarlo prima che la funzione finisca, e questo lo sai fare

Beh, una qualche utilità la avrebbe, comunque
Ma con arduino diventa duretta...
Per paolo311
Se si ridefinissero (overloading) anche gli operatori [ ] un oggetto di una tale classe sarebbe indistinguibile nell'uso da un array, o sbaglio?

Standardoil:
Se si ridefinissero (overloading) anche gli operatori [ ] un oggetto di una tale classe sarebbe indistinguibile nell'uso da un array, o sbaglio?

Diciamo che ci assomiglia.. :slight_smile:

Però tieni presente che una cosa del genere ha senso solo se hai dei metodi a corredo dell'array che manipolano in modo particolare i dati memorizzati, oppure se vuoi vincolare in qualche modo l'accesso diretto ai dati.

Tant'è che l'allocazione con il new funziona anche a "secco"..

  byte* mdaob;
  int size = analogRead(A0);
  mdaob = new byte[size];
  

  Serial.println(size);
  for (int i = 0; i < size; i++)
  {
    Serial.println(mdaob[i]);
  }

PS. Grazie del complimento, però per me riprendere a sviluppare in c\c++ è come guidare dopo tanti anni una macchia senza servosterzo.

Grazie
Ciao

E così ricadiamo nella mia prima risposta, dove però io usavo una alloc () non conoscendo io bene il c++
Si, in effetti le soluzioni quelle sono...

Standardoil:
Ma tu hai letto le mie risposte?

Ho letto tutto ma non trovato una soluzione alle tue due risposte.

Standardoil:
Tu saresti (leggo dalla tua presentazione) un po' arrugginito?
Quando riprenderai appieno cosa farai?
Riscriverai lo IDE per farlo girare su una MEGA?

Sono arrugginito su questo argomento in tale post che io ho pubblicato.

Diciamo che il progetto è di creare una libreria che implementi un mio protocollo seriale con real time interno e vorrei avere come parametro il numero di byte massimi che il buffer di ricezione può contenere ed il numero di byte massimi che la funzione interna del Real Time mi invia al colpo in base ad un tempo prefissato.

NB: il blocco Real Time è una funzione a parte e serve solo per aggiornare i dati per una sicurezza di stabilità quindi può essere anche disattivato e l'invio e la recezione funzionano tranquillamente.

E visto che sono programmatore di PLC dove si lavora a linguaggio grafico a blocchi mi viene naturale generare delle librerie come se fossero i blocchi funzionali come le Macro nel PLC o più semplicemente funzioni e quindi desidero farlo bene in modo robusto per poi anche pubblicarle con tutta la documentazione :slight_smile:

Io di media uso microcontrollori STM32 principalmente STM32F103C8T6 ed la versione cicciona STM32F407ZGT6 per motivi di presentazioni elevate (overclok, tanti GPIO e potenza da 32bit).

Ma come regola cerco sempre di fare girare il codice su un ATMega328P per esser sicuro che anche un micro ad 8 bit "semplice" lo supporti poiché noto di più gli errori come calcoli sulla latenza ecc (tramite l'oscilloscopio) per poi usarlo su Micro un po' più seri...

paolo311:
Perdonami, ma "interno" rispetto a cosa?

Se intendi dichiarare un array "interno" ad una funzione e aspettarti che mantenga lo stato anche fuori, devi cambiare la logica perchè questo non accadrà mai, una volta usciti dal blocco le variabili dichiarate in esso non sono più referenziabili a meno di non usare i trucchi che ti hanno già indicato (appoggi il riferimento su un alias globlale o con scope più ampio e poi lo vai a riprendere, etc..)

Oppure cambi la logica, la funzione può diventare un metodo di classe, all'interno della quale c'è un membro privato che è l'array, in questo modo l'array resta nascosto ma mantiene lo stato all'uscita dal metodo

Una cosa così:

#include <Arduino.h>

class MyDumbArrayOfBytes
{
private:
    byte* internalArray;
    int size;

public:
    MyDumbArrayOfBytes(int _size);
    ~MyDumbArrayOfBytes();

void Set(int _index, byte _value);
    byte Get(int _index);
    int Size();
};

MyDumbArrayOfBytes::MyDumbArrayOfBytes(int _size)
{
    internalArray = new byte[_size];
    size = _size;
}

MyDumbArrayOfBytes::~MyDumbArrayOfBytes()
{ }

void MyDumbArrayOfBytes::Set(int _index, byte _value)
{
    internalArray[_index] = _value;
}

byte MyDumbArrayOfBytes::Get(int _index)
{
    return internalArray[_index];
}

int MyDumbArrayOfBytes::Size()
{
    return size;
}




Che si può usare così:


#include <Arduino.h>
#include <MyDumbArrayOfBytes.h>

void setup()
{
  Serial.begin(9600);

MyDumbArrayOfBytes mdaob(analogRead(A0));

Serial.println(mdaob.Size());
  for (int i = 0; i < mdaob.Size(); i++)
  {
    Serial.println(mdaob.Get(i));
  }
}




Per adattarlo alle tue necessità devi effettuare una scelta, o separi il metodo che alloca l'array da quello che lo utilizza e in questo caso la classe va più o meno bene così, oppure se vuoi mantenere la logica attuale devi dotarti di flagettino che setti a true alla prima inizializzazione e lo testi sulle successive in modo da non ripetere l'allocazione dell'array.

Ciao

Intendo interna alla Libreria che desidero creare.

IN SPECIFICO:

Vorrei fare una libreria dove adotta un protocollo seriale per mandare dati binari ovvero singoli bit e quindi tale libreria deve avere come parametri il numero di bit in ingresso in modo da "collegarlo" direttamente ad un PIN della scheda dichiarato ingresso ed il numero di bit d'uscita usati per comandare direttamente un PIN digitale. (Può valere anche con i Bytes la logica per il calcolo dei Byte tramite i Bit o viceversa la so fare).

La libreria fa praticamente tutto; invio e recezione dati tramite bit che gestisco io dal programma nel loop. Ci sono ovviamente parametri d'indirizzo, marcatori ecc ma la cosa che non so fare è rendere flessibile la libreria e far scegliere all'utente quanti sengali digitali (bit) inviare e quanti ricevere.

(Sto leggendo e cercando di apprendere il più possibile dalle risposte e noto che ci sono molte cose sul codice mai viste)

Sempre per Paolo311 il tuo codice sembra proprio letto velocemente a quello che pensavo con le corrispettive funzioni di writer e read ma non capisco da dove sia stato tirato fuori il nome "mdaob" e poi il codice è tutto intero o è diviso uno nel file.h e le funzioni nel file.ccp ? Perché vedo le dichiarazioni delle variabili e poi subito sotto le funzioni di Get() Set() ecc ecc XD sono confuso di librerie non ne ho fatte molte ma ho sempre usato due file uno .h e uno .ccp e avvolte vedendo librerie di altri hanno tanti file .h penso o tanti file ccp. Sono confuso XD

Se uno sa o ha usato librerie che implementano tale metodo le condivida così forse leggendo il loro interno capsico bho XD

non credo che tu abbia letto le mie risposte, per due ragioni:

  1. non hai nemmeno capito quando scrivo a te e quando no
  2. ci sono scritte, nelle mie risposte, tutte e due le "sole" due soluzioni possibili, di una poi ti è stata anche indicata la versione c++
    inoltre:
  3. tu hai già trovato e letto le librerie che fanno quello che cerchi, hai esattamente trovato quello che ti indicavo io, ma non ne hai fatto niente
    e quindi? cosa aspetti adesso a prenderti un buon libro e a studiare quello che ti abbiamo detto?
    credimi: è escluso che, ad esempio, io ti scriva la tua "funzione magica", fai molto prima a studiare
    per il resto: buon viaggio

Partiamo dall'inizio, tu hai questo problema: devi dichiarare un array quando non sai ancora la sua dimensione.

Una delle soluzioni disponibili è quella che ti ho mostrato: dichiari un puntatore e poi quando conosci la dimensione dell'array, lo inizializzi con il numero di valori che ti serve.

La classe è un "fiorellino" in più perchè permette di definire con precisione lo scope dell'array, e di aggiungere metodi specifici per manipolarlo.

MizzardNet:
Sempre per Paolo311 il tuo codice sembra proprio letto velocemente a quello che pensavo con le corrispettive funzioni di writer e read ma non capisco da dove sia stato tirato fuori il nome "mdaob"

"mdaob" è arbitrario, è il nome di una variabile di tipo MyDumbArrayOfBytes

MizzardNet:
e poi il codice è tutto intero o è diviso uno nel file.h e le funzioni nel file.ccp ?

Le best pratices c++ credo che indichino di creare per ogni classe un file *.h con le dichiarazioni e un file *.cpp con l'implementazione, io però sono pigro (estremamente pigro..) quindi, sacrifico una regola "da manuale" a favore di una maggiore leggibilità e minore dispersione.

P.

Standardoil:
non credo che tu abbia letto le mie risposte, per due ragioni:

  1. non hai nemmeno capito quando scrivo a te e quando no
  2. ci sono scritte, nelle mie risposte, tutte e due le "sole" due soluzioni possibili, di una poi ti è stata anche indicata la versione c++
    inoltre:
  3. tu hai già trovato e letto le librerie che fanno quello che cerchi, hai esattamente trovato quello che ti indicavo io, ma non ne hai fatto niente
    e quindi? cosa aspetti adesso a prenderti un buon libro e a studiare quello che ti abbiamo detto?
    credimi: è escluso che, ad esempio, io ti scriva la tua "funzione magica", fai molto prima a studiare
    per il resto: buon viaggio

Senti in poche parole le tue risposte non sono state esaustive come quelle di paolo311 ed non serve alzare la cresta approfittando del fatto di aver sbagliato a rispondere ad una tua risposta riferita ad qualcun'altro, non hai messo i "quote" e dalla mia visione sembrava fosse riferita a me tutto qui.

Poi non ho trovato affatto librerie che fanno al caso mio e l'unica che ha quello che cerco l'ho postata in file .zip e l'ho fatto se qualcuno è in grado di spiegarmi con funziona il codice per poi così utilizzarlo nelle mie librerie personali.

Io vedo solo una tua versione, io vedo dalla seconda risposta un codice esempio che non ho capito e non riesco ad implementarlo rispetto a quello di paolo311 che ok sarà simile al tuo come hai detto tu in un'altra risposta dove però hai usato un alloc()...

Standardoil:
E così ricadiamo nella mia prima risposta, dove però io usavo una alloc () non conoscendo io bene il c++
Si, in effetti le soluzioni quelle sono...

E poi è facile dire "studia c" e fine... non so... qualche suggerimento di libri su C buoni ?
Tranquillo che non mi aspetto il "codice magico" da te... mi bastano avanzano le tue risposte inconcludenti.

Paolo 311 mi ha fatto capire meglio.

paolo311:
Partiamo dall'inizio, tu hai questo problema: devi dichiarare un array quando non sai ancora la sua dimensione.

Una delle soluzioni disponibili è quella che ti ho mostrato: dichiari un puntatore e poi quando conosci la dimensione dell'array, lo inizializzi con il numero di valori che ti serve.

La classe è un "fiorellino" in più perchè permette di definire con precisione lo scope dell'array, e di aggiungere metodi specifici per manipolarlo.

"mdaob" è arbitrario, è il nome di una variabile di tipo MyDumbArrayOfBytes

Le best pratices c++ credo che indichino di creare per ogni classe un file *.h con le dichiarazioni e un file *.cpp con l'implementazione, io però sono pigro (estremamente pigro..) quindi, sacrifico una regola "da manuale" a favore di una maggiore leggibilità e minore dispersione.

P.

Ahh si vero il nome mdaob è il nome dell'istanza MyDumbArrayOfBytes usata nel progretto vero.
Quindi il codice con le funzioni lo metto tutto interno in un file con un determianto nome ? con l'estensione .h ?

Ho provato a mettere il codice .h in un file e l'altro nel progetto principale e mi fa errore di compilazione.
I file sono tutti e due nella stessa cartella.
Il nome del file è MyDumbArrayOfBytes.h

Codice erorre:

Arduino:1.8.5 (Windows 10), Scheda:"Arduino/Genuino Uno"

C:++++++++++++\AppData\Local\Temp\cc2zQSTq.ltrans0.ltrans.o: In function `main':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/main.cpp:46: undefined reference to `loop'

collect2.exe: error: ld returned 1 exit status

exit status 1
Errore durante la compilazione per la scheda Arduino/Genuino Uno.

Questo report potrebbe essere più ricco di informazioni abilitando l'opzione
"Mostra un output dettagliato durante la compilazione"
in "File -> Impostazioni"

Chiedo subito perchè so' che c'è qualcosa che mi sfugge.

MizzardNet:
.......serve alzare la cresta approfittando del fatto di aver sbagliato a rispondere ad una tua risposta riferita ad qualcun'altro, non hai messo i "quote" e dalla mia visione sembrava fosse riferita a me tutto qui.

Poi non ho trovato affatto librerie che fanno al caso mio e l'unica che ha quello che cerco l'ho postata in file .zip e l'ho fatto se qualcuno è in grado di spiegarmi con funziona il codice per poi così utilizzarlo nelle mie librerie personali.

Io vedo solo una tua versione, io vedo dalla seconda risposta un codice esempio che non ho capito e non riesco ad implementarlo rispetto a quello di paolo311 che ok sarà simile al tuo come hai detto tu in un'altra risposta dove però hai usato un alloc()...

E poi è facile dire "studia c" e fine... non so... qualche suggerimento di libri su C buoni ?
Tranquillo che non mi aspetto il "codice magico" da te... mi bastano avanzano le tue risposte inconcludenti.

chiedo scusa alla moderazione per la citazione quasi completa, ma ci sono talemtnte tanti spunti che non potevo evitare
per lo OP

  1. non sono io che alzo la cresta, se misurassimo la "lunghezza" delle risposte, sarebbe evidente chi sta "alzando" qualcosa... e non serve nemmeno accusarmi di non aver messo i tag, sei TU che non hai capito, non io che ho sbagliato, infatti altri hanno capito benissimo
  2. che tu non abbia trovato librerie che fanno al caso tu ci credo, non le sai "capire", nemmeno quando te le spiegano
    _digitalValues = (uint8_t *)malloc(numberOfShiftRegisters * sizeof(uint8_t));

questa riga viene esattamente dalla libreria che hai allegato tu
e funziona esattamente come ti ho spiegato io nel mio post #1 (il primo che hai letto)
la riga si legge:
assegni a puntatore il risultato di un cast a tipo specifico del puntatore restituito da una malloc che alloca la memoria calcolata con la sizeof
prova a dirmi che non è quello che ti ho scritto al post #1; se non sei capace non lamentarti e non accusare gli altri. Per tua norma, se mi accusi ancora una volta di un fatto non vero ti segnalo alla moderazione
3) che tu non abbia capito il codice esempio non mi stupisce, anche perchè nella mia altra risposta io ho usato una malloc(), non sei nemmeno andato a vedere, hai solo copincollato risposte a casaccio
4)è facile dire studia il 'C', però io non solo lo ho detto, ho anche fatto: ho un intero trhead "aiutateci ad aiutarvi" che tu non hai nemmeno cercato, sei venuto qui, hai chiesto e adesso aspetti che ti diano la "pappa fatta" (che è un mio altro trehad al riguardo)
se tu, non dico avessi cercato, ma solo ti fossi minimamente guardato intorno, avresti trovato TUTTE le info che ti servono, invece aspetti solo la "soluzione", che oltretutto deve essere anche facile da capire per te, altrimenti non la riconosci e ti metti a accusare

quindi non mi rimane da dirti che:
buon viaggio

PS spero che tutto questo rimanga qui, a futura memoria........

Standardoil:
... se mi accusi ancora una volta di un fatto non vero ti segnalo alla moderazione ...

... io leggo e vedo TUTTO, anche se non intervengo ... ora prego entrambi di abbassare i toni e riportare il tutto ad una normale discussione tecnica. Grazie.

Guglielmo