none
Lettura di un file di interi in una sola volta. Inaffidabilità RRS feed

  • Domanda

  • Ciao a tutti, 

    ho già formulato questa domanda ed ho ottenuto la risposta. Sembrava perfetta:

    pi = (int*)Marshal.UnsafeAddrOfPinnedArrayElement(File.ReadAllBytes(fileName),0);

    sotto unsafe naturalmente. Rispondeva esattamente alle mie aspettative.
    Purtroppo ho scoperto che non è affidabile. Sembra funzionare tutto bene poi improvvisamente, senza motivo apparente pi [j] dà valori di tipo NaN.
    Ho il sospetto che la memoria venga riutilizzata (garbage collector?)
    in sostanza non sei sicuro di poter utilizzare questa istruzione fino a quando vuoi.

    Suggerimenti ??




    giovedì 24 febbraio 2022 13:25

Risposte

  • Grazie  fabiocaruso , chiara la tua spiegazione

    a questo punto :

    • non posso  " fissare " un puntatore inserito in un vettore di puntatori
    • non posso usare il puntatore " fissato " al di fuori della funzione che lo crea

    se così stanno le cose non posso utilizzarlo , perchè mi servono entrambe le situazioni di cui  sopra

    quindi devo tornare al vecchio   for ()  copiando i singoli record dal file ad una memoria    Marshal.AllocHGlobal( );

    peccato , questo nuovo C  ( C# ) lo trovo troppo " ingessato "  per i miei gusti,

    ho davvero nostalgia del vecchio  C  , ora c'è un'esagerata ( per me ) attenzione al giusto  cast

    capisco l'intenzione di evitare errori , ma questa è responsabilità di chi scrive codice

    Grazie  comunque  a  tutti  per  l'attenzione, alla prossima

    • Contrassegnato come risposta vittorio 50 sabato 26 febbraio 2022 08:54
    sabato 26 febbraio 2022 08:54

Tutte le risposte

  • Infatti, hai ragione: per evitare la Garbage Collection, devi fare l'assegnazione di pi dentro un'istruzione "fixed", così:

                unsafe
                {
                    fixed (int* pi = (int*)Marshal.UnsafeAddrOfPinnedArrayElement(File.ReadAllBytes(fileName), 0))
                    {
                       //qua metti il tuo codice che utilizza pi
                    }
                }

    giovedì 24 febbraio 2022 14:58
  • Buongiorno Vittorio, 

    Con il suggerimento di Fabio, hai risolto il problema?


    • Microsoft offre questo servizio gratuitamente, per aiutare gli utenti e aumentare il database dei prodotti e delle tecnologie. Il contenuto fornito “as is“ non comporta alcuna responsabilità da parte dell’azienda.

    venerdì 25 febbraio 2022 08:24
    Moderatore
  • Grazie  fabiocaruso e Yordan

    ci provo e farò sapere

    venerdì 25 febbraio 2022 08:48
  • Per  fabiocaruso  e  Yordan ,

    in realtà il puntatore è un elemento di un vettore di puntatori ( indice rc ) : 

                fixed (int* pi[rc] = (int*)Marshal.UnsafeAddrOfPinnedArrayElement(File.ReadAllBytes( filename ), 0)) ;

    e viene utilizzato globalmente, non solo nella stessa funzione dove viene creato

    Sarà per questo forse ma mi dà errore :              non è possibile usare l'espressione specificata in un' istruzione fixed

    P.S.  come  mai  improvvisamente il carattere diventa  più piccolo ??

    venerdì 25 febbraio 2022 09:03
  • P.S.  come  mai  improvvisamente il carattere diventa  più piccolo ??

    Per causa del editor ed il codice che uno inserisce. Ci sono alcuni azioni che lo fanno diventare cosi. 

    • Microsoft offre questo servizio gratuitamente, per aiutare gli utenti e aumentare il database dei prodotti e delle tecnologie. Il contenuto fornito “as is“ non comporta alcuna responsabilità da parte dell’azienda.

    venerdì 25 febbraio 2022 09:52
    Moderatore
  • Ti da errore perchè non puoi usare un vettore o una matrice, come puntatore, dentro un'istruzione fixed. E ti da errore pure se utilizzi un .NET (Framework) diverso da .NET 5.0 e da .NET 6.0.

    Altrimenti, per come l'ho scritta io sopra, funziona.

    La riga contenente l'istruzione "fixed" dev'essere seguita da una coppia di parentesi graffe dentro cui va il codice per il quale l'area di memoria puntata dal suddetto "int* pi" non sarà soggetta a Garbage Collection, e quindi la relativa posizione nella RAM resterà invariata.

    venerdì 25 febbraio 2022 18:00
  • Grazie  fabiocaruso , chiara la tua spiegazione

    a questo punto :

    • non posso  " fissare " un puntatore inserito in un vettore di puntatori
    • non posso usare il puntatore " fissato " al di fuori della funzione che lo crea

    se così stanno le cose non posso utilizzarlo , perchè mi servono entrambe le situazioni di cui  sopra

    quindi devo tornare al vecchio   for ()  copiando i singoli record dal file ad una memoria    Marshal.AllocHGlobal( );

    peccato , questo nuovo C  ( C# ) lo trovo troppo " ingessato "  per i miei gusti,

    ho davvero nostalgia del vecchio  C  , ora c'è un'esagerata ( per me ) attenzione al giusto  cast

    capisco l'intenzione di evitare errori , ma questa è responsabilità di chi scrive codice

    Grazie  comunque  a  tutti  per  l'attenzione, alla prossima

    • Contrassegnato come risposta vittorio 50 sabato 26 febbraio 2022 08:54
    sabato 26 febbraio 2022 08:54