Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente bannato
    Registrato dal
    Jun 2003
    Messaggi
    3,657

    [C++] Doppio puntatore e problemi di cui non capisco la causa

    Ciaoa a tutti,
    ho fatto una piccola applicazione che calcola il Determinante di una matrice quadrata. Ecco il codice del main (e li dove si verifica il tutto):

    codice:
    int main()
    {
    	int **matrix;
    	int n;
    	ifstream leggi;
    	leggi.open("input.txt");
    	//leggo l'ordine della matrice 
    	leggi>>n;
    	//istanzio la matrice
    	matrix = new (int *);
    	for(int i =0;i<n;i++)
    	{
    		matrix[i]=new int;
    	}
    	//leggo la matrice da file
    	for (int riga=0;riga<n;riga++)
    	{
    		for (int colonna=0;colonna<n;colonna++)
    		{
    			leggi>>matrix[riga][colonna];
    		}
    	}
    	
    	for (int riga=0;riga<n;riga++)
    	{
    		for (int colonna=0;colonna<n;colonna++)
    		{
    			
    			cout<<matrix[riga][colonna]<<" ";
    		}
    		cout<<"\n";
    	}
    	
    	cout<<"Il determinante della matrice è: "<<Determinante(matrix,n);
    	
    	
    	delete matrix;
    }
    il problema sta nel fatto che, se io gli dico di leggere una matrice 3x3 (il leggi>>n prende il primo numero dal file che indica l'ordine della matrice, 3x3, 4x4 etc.)

    Se prende 3, ok, se prende 2, ok, se prende 4 guardate le belle cose che mi dice

    $ g++ -pedantic -Os determinante.cpp -o determinante
    determinante.cpp:90:2: warning: no newline at end of file
    >Exit code: 0
    $./determinante
    *** glibc detected *** ./determinante: free(): invalid next size (fast): 0x0804c178 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6[0xb7d4c8bd]
    /lib/tls/i686/cmov/libc.so.6(__libc_free+0x84)[0xb7d4ca44]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7efbfc1]
    ./determinante(__gxx_personality_v0+0x34e)[0x8048af2]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7cfb8cc]
    ./determinante(__gxx_personality_v0+0x6d)[0x8048811]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 16:06 153028 /home/tuttoweb/documenti/programmazione/c++/determinante/determinante
    08049000-0804a000 rw-p 00000000 16:06 153028 /home/tuttoweb/documenti/programmazione/c++/determinante/determinante
    0804a000-0806b000 rw-p 0804a000 00:00 0 [heap]
    b7b00000-b7b21000 rw-p b7b00000 00:00 0
    b7b21000-b7c00000 ---p b7b21000 00:00 0
    b7ce5000-b7ce6000 rw-p b7ce5000 00:00 0
    b7ce6000-b7e13000 r-xp 00000000 16:06 294929 /lib/tls/i686/cmov/libc-2.4.so
    b7e13000-b7e15000 r--p 0012c000 16:06 294929 /lib/tls/i686/cmov/libc-2.4.so
    b7e15000-b7e17000 rw-p 0012e000 16:06 294929 /lib/tls/i686/cmov/libc-2.4.so
    b7e17000-b7e1a000 rw-p b7e17000 00:00 0
    b7e1a000-b7e24000 r-xp 00000000 16:06 262211 /lib/libgcc_s.so.1
    b7e24000-b7e25000 rw-p 00009000 16:06 262211 /lib/libgcc_s.so.1
    b7e25000-b7e49000 r-xp 00000000 16:06 294933 /lib/tls/i686/cmov/libm-2.4.so
    b7e49000-b7e4b000 rw-p 00023000 16:06 294933 /lib/tls/i686/cmov/libm-2.4.so
    b7e4b000-b7f1f000 r-xp 00000000 16:06 297220 /usr/lib/libstdc++.so.6.0.8
    b7f1f000-b7f22000 r--p 000d4000 16:06 297220 /usr/lib/libstdc++.so.6.0.8
    b7f22000-b7f24000 rw-p 000d7000 16:06 297220 /usr/lib/libstdc++.so.6.0.8
    b7f24000-b7f2b000 rw-p b7f24000 00:00 0
    b7f38000-b7f3a000 rw-p b7f38000 00:00 0
    b7f3a000-b7f53000 r-xp 00000000 16:06 262168 /lib/ld-2.4.so
    b7f53000-b7f55000 rw-p 00018000 16:06 262168 /lib/ld-2.4.so
    bfb21000-bfb37000 rw-p bfb21000 00:00 0 [stack]
    ffffe000-fffff000 ---p 00000000 00:00 0 [vdso]
    0 7 2 2
    -1 5 1 2
    0 0 1 -1
    0 4 0 2
    Il determinante della matrice è: 3Aborted (core dumped)
    >Exit code: 134
    voi ci capite qualcosa?

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    La matrice non e' allocata/liberata correttamente e quando va a leggere i dati, accede a zone di memoria non lecite.

    Quando allochi deve essere

    codice:
    matrix = new int*[n];
    for(i=0;i<n;i++)	
       matrix[i] = new int[n];
    e quando liberi

    codice:
    for(i=0;i<n;i++)	
      delete matrix[i];
    delete matrix;

  3. #3
    Originariamente inviato da oregon


    ...
    e quando liberi

    codice:
    for(i=0;i<n;i++)	
      delete matrix[i];
    delete matrix;
    o forse?

    .....
    delete [] matrix;
    ciao
    sergio

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da mondobimbi
    o forse?

    .....
    delete [] matrix;
    ciao
    sergio
    Formalmente sì, ma il compilatore (nel mio caso VC2005) e' abbastanza "smart" da capire cosa sta facendo ... infatti, a livello di codice compilato, per le due forme

    codice:
    	delete matrix;
    00411CFD 8B 45 F8         mov         eax,dword ptr [matrix] 
    00411D00 89 85 14 FF FF FF mov         dword ptr [ebp-0ECh],eax 
    00411D06 8B 8D 14 FF FF FF mov         ecx,dword ptr [ebp-0ECh] 
    00411D0C 51               push        ecx  
    00411D0D E8 D8 F4 FF FF   call        operator delete (4111EAh) 
    00411D12 83 C4 04         add         esp,4 
    
    	delete [] matrix;
    00411CFD 8B 45 F8         mov         eax,dword ptr [matrix] 
    00411D00 89 85 14 FF FF FF mov         dword ptr [ebp-0ECh],eax 
    00411D06 8B 8D 14 FF FF FF mov         ecx,dword ptr [ebp-0ECh] 
    00411D0C 51               push        ecx  
    00411D0D E8 0B F9 FF FF   call        operator delete[] (41161Dh) 
    00411D12 83 C4 04         add         esp,4
    come puoi vedere, non c'e' differenza.

    Ciao

  5. #5
    Originariamente inviato da oregon
    Formalmente sì, ma il compilatore (nel mio caso VC2005) e' abbastanza "smart" da capire cosa sta facendo ... infatti, a livello di codice compilato, per le due forme

    codice:
    	delete matrix;
    00411CFD 8B 45 F8         mov         eax,dword ptr [matrix] 
    00411D00 89 85 14 FF FF FF mov         dword ptr [ebp-0ECh],eax 
    00411D06 8B 8D 14 FF FF FF mov         ecx,dword ptr [ebp-0ECh] 
    00411D0C 51               push        ecx  
    00411D0D E8 D8 F4 FF FF   call        operator delete (4111EAh) 
    00411D12 83 C4 04         add         esp,4 
    
    	delete [] matrix;
    00411CFD 8B 45 F8         mov         eax,dword ptr [matrix] 
    00411D00 89 85 14 FF FF FF mov         dword ptr [ebp-0ECh],eax 
    00411D06 8B 8D 14 FF FF FF mov         ecx,dword ptr [ebp-0ECh] 
    00411D0C 51               push        ecx  
    00411D0D E8 0B F9 FF FF   call        operator delete[] (41161Dh) 
    00411D12 83 C4 04         add         esp,4
    come puoi vedere, non c'e' differenza.

    Ciao
    come non c'è differenza, le due chiamate sono ad indirizzi differenti.
    La chiamata a
    delete matrix;
    disalloca solo il primo elemento.
    ciao
    sergio

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    L'indirizzo e' differente perche' viene chiamato l'operatore delete [] al posto del delete.
    In effetti mi ero dimenticato di mostrarti che l'operatore delete [] e' definito con

    codice:
    void operator delete[]( void * p )
    {
        RTCCALLBACK(_RTC_Free_hook, (p, 0))
    
        operator delete(p);
    }
    e come puoi vedere (a meno della prima indicazione che e' usata solamente per il debug), il tutto si risolve alla corrispondente chiamata all'operatore delete a cui viene passato il puntatore originale. Avviene tutto all'interno del codice dell'operatore delete.

    E poi perche' parli di "primo elemento"? La deallocazione avviene del "blocco di memoria" costituito dallo spazio necessario ad allocare n puntatori, spazio che e' contiguo in memoria.

  7. #7
    l'uso dell'operatore delete invece di delete [] su degli array allocati dinamicamente dà risultati non definiti dalle specifiche del c++, l'implementazione è lasciata libera al compilatore, molte volte questi disallocano solo il primo elemento.
    Non conosco il comportamento di VC2005 ma se si vuole scrivere codice portabile è meglio disallocare sempre gli array con delete [] .
    ciao
    sergio

  8. #8
    Utente bannato
    Registrato dal
    Jun 2003
    Messaggi
    3,657
    alla fine come si deleta?

  9. #9
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Beh ... il discorso mi e' sembrato abbastanza chiaro ...

  10. #10
    Utente bannato
    Registrato dal
    Jun 2003
    Messaggi
    3,657
    Originariamente inviato da oregon
    La matrice non e' allocata/liberata correttamente e quando va a leggere i dati, accede a zone di memoria non lecite.

    Quando allochi deve essere

    codice:
    matrix = new int*[n];
    for(i=0;i<n;i++)	
       matrix[i] = new int[n];
    e quando liberi
    non voglio aprire un altro thread, ma ho questo problema

    codice:
    modulo **castello;
    	
    input.open("input.txt");
    input>>r;input>>c;
    	
    castello = new modulo *[r];
    for(int i =0;i<r;i++)
    {
    		castello[i]=new modulo [c];
    }
    dove modulo è una struct così definita

    struct modulo
    {
    char visitato;
    modulo *to_west;
    modulo *to_north;
    modulo *to_east;
    modulo *to_south;
    };


    mi dice:
    terminate called after throwing an instance of 'std::bad_alloc'
    what(): St9bad_alloc
    Aborted (core dumped)


    suggerimenti?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.