[C] realloc disalloca le celle nel ritorno a funzione

di il
34 risposte

34 Risposte - Pagina 3

  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Ho letto il codice. Ho un solo - importante - consiglio: sistema tutte le funzioni eliminando i parametri superflui e utilizzando al loro posto variabili locali.

    C'è poco da dire, e lo dico chiaramente e sinceramente: più lo leggo, e più ritengo che vada riguardato (e riscritto) riga per riga.
    Dico ciò nonostante il codice funzioni correttamente nel 50% degli scenari.

    Passo il testimone a persone più temerarie di me
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Lampo1089 ha scritto:


    No non l'ho provato, però a questo punto ti direi di riflettere sulle osservazioni che ti ho fatto, verificando che il codice che ti ho proposto sia effettivamente corretto.
    Cvd, la fix che ti ho suggerito non è corretta. Manca ancora la modifica del valore puntato da linguaggio_2_f con quanto ritornato dalla realloc. Prova a ragionarci su...
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Nulla ci sto provando ormai da un po e non ci sono arrivato purtroppo, penso sia una parte o che non mi è stata spiegata al meglio o che non ho ben approfondito e speravo di capirla ma purtroppo non ce la sto facendo, a sto punto penso che l unica cosa sia di eliminare tutte quelle funzioni che mi permettevano la realloc per fare un programmino piu completo e rimanere senza. non so cosa fare le ho provate con tutte le mie forze..
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    In crea_linguaggio_1, sostituisci quello che hai scritto nell'if di continuazione con questo.
    
           if (continua == 1)
            {
                /* richiesta all'utente dei dati per l'allocazione del linguaggio */
                int old_num_seq = *num_sequenze_1;
                *num_sequenze_1 += richiedi_righe_linguaggio(esito_lettura);
                linguaggio_1 = (char**)realloc(linguaggio_1, *num_sequenze_1 * sizeof(char*));
                *linguaggio_1_f = linguaggio_1;
                for (copia_i = old_num_seq; copia_i < *num_sequenze_1; copia_i++)
                {
                    linguaggio_1[copia_i] = (char*)malloc(*lunghezza_sequenza_1 * sizeof(char));
                }
            }
    
    Il motivo per cui crashava - e crashava nelle riallocazioni eseguite nel for loop - è che tentava di riallocare memoria a casaccio.
    Spiego meglio:
    1) la prima realloc su linguaggio_1 ti rialloca la memoria da lui puntata: quello che hai già scritto rimane inalterato (potenzialmente copiato da un'altra parte), ma il resto non è inizializzato (https://en.cppreference.com/w/c/memory/reallo)
    The reallocation is done by either:

    a) expanding or contracting the existing area pointed to by ptr, if possible. The contents of the area remain unchanged up to the lesser of the new and old sizes. If the area is expanded, the contents of the new part of the array are undefined.
    2) a questo punto, la vecchia versione del codice, riallocava correttamente le sequenze già inserite (domanda: era proprio necessario?), ma appena arriva al primo elemento nuovo tenta di riallocare un'area di memoria non definita eg prima avevi 4 sequenze, dici di volerne una aggiuntiva, alla iterazione del for in cui copia_1 = 4 leggi riallochi il contenuto di linguaggio_1[4] che punta a un indirizzo di memoria non definito, causando il crash.

    Nella mia prova, questo ha risolto il crash che si ottiene con gli steps che hai descritto.

    Immagino che una Identica modifica vada fatta nell'altra funzione.

    Se ritieni debba essere necessario riallocare tutte le sequenze - e non allocare solo quelle nuove come ho fatto io - essendo chiaro ora quale fosse il problema, la modifica dovrebbe essere facile.
  • Re: [C] realloc disalloca le celle nel ritorno a funzione

    Aggiungo: consiglio di fare un bel giro del programma con un address sanitizer - è un programma che rileva accessi alla memoria non validi e problemi simili.
    Non ho idea del tuo setup, su windows uso visual studio e c'è una opzione di compila apposita che lo abilita (https://docs.microsoft.com/it-it/cpp/sanitizers/asan?view=msvc-170)

    Questo è l'output: direi che il problema sono le dimensioni dei buffer troppo piccoli, come già fatto notare in precedenza per l'array alfabeto, ma lo stesso problema è presente in tutti i buffer allocati.
    
    Utilizza l'alfabeto per la creazione di 2 linguaggi.    {a e i o u  }.
    Crea il primo linguaggio!
    Quante sequenze finite di simboli, presi dall'alfabeto, vuoi aggiungere all'interno del linguaggio? (>= 0)  4
    Quale sara' la lunghezza massima della sequenza (>0)  2
    
    Inserisci la sequenza 1 rispettando la lunghezza scelta:   aa
    =================================================================
    ==5952==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x124543320092 at pc 0x7ffcfd563e1e bp 0x007e2218f600 sp 0x007e2218f608
    READ of size 3 at 0x124543320092 thread T0
    ==5952==WARNING: Failed to use and restart external symbolizer!
        #0 0x7ffcfd563e50 in _asan_wrap_GlobalSize+0x41186 (C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\bin\HostX86\x64\clang_rt.asan_dbg_dynamic-x86_64.dll+0x180043e50)
        #1 0x7ff6376a197a in inserisci_sequenze Project1\main.c:420
        #2 0x7ff6376a142a in crea_linguaggio_1 Project1\main.c:311
        #3 0x7ff6376a1c21 in main Project1\main.c:154
        #4 0x7ff6376a30a8 in invoke_main d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
        #5 0x7ff6376a2ffd in __scrt_common_main_seh d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
        #6 0x7ff6376a2ebd in __scrt_common_main d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:330
        #7 0x7ff6376a311d in mainCRTStartup d:\agent\_work\4\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:16
        #8 0x7ffd65127033 in BaseThreadInitThunk+0x13 (C:\WINDOWS\System32\KERNEL32.DLL+0x180017033)
        #9 0x7ffd67122650 in RtlUserThreadStart+0x20 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x180052650)
    
Devi accedere o registrarti per scrivere nel forum
34 risposte