Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 39
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2001
    Messaggi
    20

    problemi con malloc()

    Ciao gurus.
    Io ho un grosso problema.
    Un errore incomprensibile nel mio codice mi impedisce di proseguire.

    Si tratta di un programma in C++, composto da più file:
    i file contengono rispettivamente, il main, funzioni, classi (una classe o una funzione per ogni file).
    C'è poi un header.h che includo all'inizio di quasi tutti i file.
    La programmazione è di tipo modulare, cioè, a parte per una costante, non faccio uso di variabili globali, ma passo ciò che serve alle funzioni per parametro.

    La compilazione è andata a buon fine e sto ora eseguendo il debug con dei file di prova in input.

    Con un file piccolo non c'è problema.
    Con un file medio invece, durante l'inizializzazione di una matrice 27 x 27 (Identica 27), viene generato un accesso violato all'interno di una malloc()

    Mi spiego meglio (Riporto in fondo al messaggio la funzione in questione, in corrispondenza della freccia il debug si blocca)

    La funzione ha lo scopo di allocare diverse strutture in base al contenuto del file di input, dopo di che deve restituire i puntatori a tali strutture ai parametri passati per indirizzo.

    Le strutture vengono allocate con la malloc(). I puntatori a tali strutture vengono prima memorizzati in variabili d'appoggio e solo alla fine della funzione, restituiti.

    Come potete notare si tratta di una comune costruzione di una matrice quadrata. Eppure quando alloco la terza riga, la stessa malloc() provoca un accesso violato, scrive dove non le è consentito.

    Spero di essere stato chiaro e spero che tra di voi ci sia qualcuno che abbia già riscontrato questo problema, oppure che conosca meglio di me il funzionamento della malloc() e dell'allocazione della memoria.

    Personalmente pensavo che poiché è la malloc() a gestire la memoria dinamica l'unico problema che potesse dare fosse l'esaurimento della memoria.

    Vi ringrazio anticipatamente per l'aiuto.

    Ciao, Danilo




    // LeggiFile non solo legge il problema dal file richiesto, ma inizializza anche alcune strutture
    void LeggiFile(char *nomefile, gestore_A *A, gestore_X *X, gestore_C *c, double ***_B, double**_w, double **_b, int *_m, int *_n, int *_svar, int *_rvar, int *_avar)
    {
    //VARIABILI
    ...

    //VARIABILI D'APPOGGIO
    int m, n, rvar, svar, avar;
    double **B;
    double *w;
    double *b;

    ...

    // inizializzo B all'identica Im
    if ( (B=(double**)malloc(sizeof(double*)*m))==NULL ) { printf("ERRORE\n"); exit(0); }

    for ( i=0 ; i<m ; i++ )
    {
    -> if ( (B[i]=(double*)malloc(sizeof(double)*m))==NULL ) { printf("ERRORE\n"); exit(0); }
    for ( j=0 ; j<m ; j++)
    {
    if (i==j)
    B[i][j]=1;
    else
    B[i][j]=0;
    }

    }

    ...

    *_m = m;
    *_n = n;
    *_rvar = rvar;
    *_svar = svar;
    *_avar = avar;
    *_B = B;
    *_w = w;
    *_b = b;

    }

  2. #2
    Non vedo dove inizializzi m, l'hai inizializzato? Se l'hai fatto dovrebe essere ok, altrimenti forse c'e' qualche altro errore di allocazione nel programma, il bello della malloc e' che magari non fallisce quando fai un errore, ma due o tre chiamate dopo .....

    Orpo pero' , sembra quel codice scritto per le gare di programmazione, dove vince chi scrive le cose + incomprensibili e allora le variabili si chiamarno _zz , __w eccetera..

    ho scritto questa prova a vedere se funzia dovrebbe essere + efficiente

    codice:
    #include <stdlib.h>
    #include <stdio.h>
    #include <memory.h>
    
    ...
    //VAR DI APPOGGIO
      size_t i=0, m=5, n=5, sz=sizeof(double);
      char ** ptr;
      char* bp; 	
      double**B;
    ....
    
      if(!(ptr=(char**)malloc(sizeof(void*)*n + sz*n*m))) exit(0);
      bp = (char*)ptr + sizeof(void*)*n;
      sz*=m,memset(bp, 0, sz*n);
      while(n-->0)ptr[n] = bp + sz*n;	
      B = (double**)ptr;
      for(;i<m;++i)mtx[i][i]=1.0;	
    ...
    Ciao

  3. #3
    1) Visto che programmi in C++ invece di malloc() usa l'operatore new. Se non sai come fare trovi riferimenti in ogni buon manuale C++. Per allocare spazio in una matrice il modo esatto è il seguente (uso malloc cosi capisci).

    double **matrix;

    matrix = (double**)malloc(10 * sizeof(double*) * sizeof(double));

    for (int i = 0; i < 10; i++)
    matrix[i] = (double)malloc(15 * sizeof(double));

    questo ti crea una matrice di tipo double 10 x 15

    Per liberare memoria in C++ usa delete (delete[]). bye

    p.s: non hai pensato di usare un debugger per capire a che punto del programma ottieni l'errore?
    There are 10 kinds of people in the world: who knows the binary numeration and who not

  4. #4
    Utente di HTML.it
    Registrato dal
    Dec 2001
    Messaggi
    20
    Io naturalomente ho usato uno strumento di debug,e so dove mi da errore. La cosa strana è che l'errore è all'interno della malloc().
    L'unica soluzione all'enigma per ora è che ci sia un bug nella malloc(), ma è assurdo!
    Oggi ho persino controllato che non venisse allocata memoria in indirizzi già riservati. Poi mi sono messo a studiare un po' come funziona la malloc(). Gestisce i blocchi di memoria con una lista doppiamente lincata e ad un certo punto si dimentica di istanziarne uno e quando ci va a scrivere genera un'eccezzione.

    Ad ogni modo se new e delete sono costrutti del c++ posso provare con quelli.

    Riguardo al tuo codice. Prima pensavo che fosse un'idea elegante, ma poi mi sono reso conto che forse c'è un errore.

    Di certo funziona, però allochi molta più memoria di quella che serve.
    Probabilmente ti sarai sbagliato.

    Il codice corretto è il seguente:

    double **matrix;

    matrix = (double**)malloc(10 * sizeof(double*));

    for (int i = 0; i < 10; i++)
    matrix[i] = (double)malloc(15 * sizeof(double));

    Comunque grazie. Ciao, Danilo

  5. #5
    Si, infatti nella fretta avevo scritto due volte la stessa cosa prima, anche se quando vai ad allocare le righe devi fare:

    matrix[i] = (double*)malloc(15 * sizeof(double));


    con new sarebbe:

    matrix = new double*[10];
    for (int i = 0; i < 10; ++i)
    matrix[i] = new double[15];


    per liberare:

    for (int i = 0; i < 10; ++i)
    delete[] matrix[i];

    delete matrix;

    bye (e scusa per lo stupido errore iniziale)
    There are 10 kinds of people in the world: who knows the binary numeration and who not

  6. #6
    Ma perche' mettete n chiamate alla malloc inutilmente? Ne basta una. Inoltre cosi' si frammenta maggiormente la memoria, infine se ne usa di piu, perche' sia il sistema, che malloc, usano parte della memoria per potere gestire i blocchi liberi e allocati.

    Secondo la mia teoria il blocco va allocato in modo che sia abbastanza grosso da contenere n puntatori, piu' la dimensione della matrice, ovvero n*m*sizeof(item), dopo di che la memoria allocata si suddivide in modo che la prima parte contenga gli n puntatori. Questi n puntatori devono essere inizializzati in modo da puntare ciascuno ad una fetta di memoria allocata sufficiente a contenere per intero una riga.

    Si potrebbe allora scrivere una funzione di uso generale per allocare qualsiasi tipo di matrice bidimensionale con una sola chiamata a malloc:

    void* AllocMatrix(size_t n, size_t m, size_t sz_item, size_t sz_ptr)
    {
    char**ptr, *bp;

    if(!(ptr=(char**)malloc(sz_ptr*n + sz_item*n*m))) return NULL;
    bp = (char*)ptr + sz_ptr*n;
    while(n-->0)ptr[n] = bp + sz_item*n;

    return (void*)ptr;
    }

    da richiamare cosi

    double**B = (double**)AllocMatrix(n,m,sizeof(double), sizeof(double*));

    e per liberare la memoria

    free(B)

    basta.

    Volendo anche inizializzare a zero la matrice in modo efficiente si puo usare memset come avevo fatto in precedenza.

    beh e' tardi
    Ciao.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2001
    Messaggi
    20
    E' una soluzione interessante la tua. In pratica costruisci la matrice con un'unica allocazione.
    E' poco intuitivo, ma elegante.
    A questo punto si potrebbe costruire la matrice con la struttura di una matrice statica. Non so come viene allocata una matrice statica, ma adesso che mi hai incuriosito controllerò.
    Il mio problema comunque è un'altro, ma adesso ho un po' di materiale su cui lavorare.

    Ciao e grazie. Danilo

  8. #8
    sei prp sicuro che il costo computazionale della tua versione sia inferiore rispetto a quella tradizionale? Io dico di no, se vuoi fai delle prove a riguardo... inoltre il fatto che la memoria sia (come dici tu) piu' frammentata non vedo che problema sia...

    bye
    There are 10 kinds of people in the world: who knows the binary numeration and who not

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2001
    Messaggi
    20
    Il costo computazionale è lo stesso in linea di massima.
    Eseguire più malloc significa comunque aumentare di un costo proporzionale a m il tempo di calcolo. C'è uno preco di memoria addizionale per i blocchi di allocazione generati dalla malloc()

    Effettivamente la frammentazione in memoria centrale non è un problema però. Anzi potrebbe essere difficile trovare m*n*sz_item + m*sz_ptr byte adiacenti e il programma non funzionerebbe per matrici molto grandi.

    Comunque va considerato che scritto più chiaramente non è un codice incomprensibile e può essere una soluzione elegante.

    Ciao, Danilo

  10. #10
    Anzi potrebbe essere difficile trovare m*n*sz_item + m*sz_ptr byte adiacenti e il programma non funzionerebbe per matrici molto grandi.
    ??? Dammi un motivo per cui non dovrebbe funzionare....


    Eseguire più malloc significa comunque aumentare di un costo proporzionale a m il tempo di calcolo
    tempo di calcolo == costo computazionale... -_-

    bye
    There are 10 kinds of people in the world: who knows the binary numeration and who not

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 © 2024 vBulletin Solutions, Inc. All rights reserved.