+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: [C/C++] Allocare dinamicamente una matrice bidimensionale

  1. #1
    matte19-94 non è in linea Novello
    Post
    27

    [C/C++] Allocare dinamicamente una matrice bidimensionale

    Ragazzi devo allocare dinamicamente una matrice, ma non so proprio come fare. Mi potreste dire voi come si fa, spiegandomi un po' i passaggi. Allocare dinamicamente una struttura mi riesce, ma per la matrice mi hanno detto che devo usare un puntatore a puntatore, e non so come fare. Programmo in c++

  2. #2
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,124
    Ciao,

    Hai due modi di allocare una matrice dinamicamente:
    1) Allocare un unico bufferone N*M e poi utilizzare banalmente l'algebra per accedere all'elemento <i,j> (sarà in posizione i*N+j o i*M+j a seconda di come memorizzi gli elementi).
    2) Allocare un buffer di righe. Ogni riga è un buffer di elementi.

    Nel primo caso non è difficile immaginare come possa funzionare l'allocazione e l'accesso agli elementi. Questa rappresentazione ha il pregio di non frammentare la memoria e di non richiedere un doppio accesso a puntatore per ottenere il dato (di contro l'accesso all'elemento risente di un calcolo aggiuntivo - che però gli ottmizzatori moderni tendono a rendere quasi irrisorio).

    Nel secondo caso la cosa non è di nuovo di difficoltà trascendentale. Dovrai prima allocare un buffer di puntatori (il buffer di righe appunto), quindi in ogni elemento di tale buffer andrà allocato un buffer di elementi.
    Per una matrice di char, ad esempio, prima dovrai allocare un char** (se ti infastidisce il doppio *, immaginalo come un char* [M]), quindi per ogni elemento di questo buffer (avrà dimensione M, supponiamo) allochi l'i-esimo elemento.
    In due parole (pseudocodice):
    codice:
    char** matrice=new char*[M]; //qui allochi M puntatori a char
    for(i=0..M){
       matrice[i]=new char[N]; //Qui allochi in ogni puntatore la memoria necessaria ad N elementi
    }
    Ciaociao
    Ultima modifica di bottomap; 08-04-2011 18:21 


    Venite a farmi un saluto su http://www.bottomap.com/

    - Come porre domande in modo intelligente
    - Hai mai dato un'occhiata al
    Regolamento del Forum? Se la risposta è no, sarebbe proprio l'ora di farlo...
    - Il Crossposting è vietato dalla Netiquette.

    "Solo Puffin ti darà forza e grinta a volontà" - Charlie O'Brian
    "I gatti sono animali verso cui ho il massimo rispetto. I gatti e i non conformisti mi sembrano davvero i soli esseri in questo mondo che abbiano una coscienza pratica e attiva" - Jerome K. Jerome
    "Dun Dun DUNNN!" - Capitan Caos
    (per chiunque se lo fosse mai chiesto, il nick Bottomap è volutamente sgrammaticato)

  3. #3
    cyd
    cyd non è in linea Novello
    Post
    33
    beh io creerei un 'vettore di vettori' che può essere o il vettore delle righe o quello delle colonne, a tuo piacimento.

    come creare questo vettore di vettori? beh se per vettore intendiamo un array e se identifichiamo l'array col puntatore alla sua prima cella è immediato che un vettore di vettori sarà banalmente un array che contiene altri array, quindi un array contenente puntatori, identificando questo array di puntatori col puntatore alla prima cella segue che la variabile che ti serve è del tipo tipo** cioè puntatore a puntatori... la diffcoltà dell'astrazione risiede unicamente nel vedere array e puntatori come due facce della stessa medaglia. e tenendo conto che in c esistono solo i puntatori, quando tu dichiari
    codice:
    int arr[N];
    stai allocando N celle di 'tipo' int e 'arr' sarà il puntatore alla prima area di memoria ( infatti le espressioni *arr e arr[0] come *(arr+1) e arr[1] sono del tutto equivalenti).

    dunque se N è il numero di righe e M quello di colonne (che precedentemente hai prelevato) e se la matrice è intesa come vettore di colonne potrai fare una roba del genere:
    codice:
    int i;
    float** a; //matrice di float
    
    // leggo  n e m
    
    a = (float*) malloc(m*sizeof(float*)); // alloco lo spazio per m puntatori a float
    
    //ora devo riempire le colonne (ognuna di n valori)
    
    for(i=0;i<n;i++){   //per ogni colonna
       
        //alloco il vettore colonna (a[i] equivale ad *(a+i) solo che devo usare questo 
        //dato che non ho usato la scrittura array-style
        *(a+i) = (float*) malloc(n*sizeof(float));
        
        //per ogni valore della colonna corrente (n == numero di righe)
        for(j=0;j<n;j++){
    	printf("riga %d valore %d (float value):",i,j);  //leggo
    	scanf("%f",&a[i][j]);
        }
    }
    se poi hai capito l'esempio saprai come operarci

  4. #4
    matte19-94 non è in linea Novello
    Post
    27
    ho provato il secondo metodo detto da Bootmap, ma qualcosa non torna..il codice sotto, va bene solo in alcuni casi. ho messo riga 3 e colonna 1, e non ha fatto nulla, e un' altra volta invece mi ha dato il seguente errore:L'istruzione a"0*7c921880" ha fatto riferimento a "0x00000000" la memoria non poteva essere read. In alcuni casi, funziona perfettamente. Come mai????? Vi ringrazio per la vostra pazienza


    codice:
    cout<<"inserisci riga?";
        cin>>riga;
        cout<<"inserisci colonna?";
        cin>>colonna;
    
    char** matrice=new char*[colonna]; 
    for(int i=0;i<colonna;i++)
    {
       matrice[i]=new char[riga]; 
    }
    Ultima modifica di matte19-94; 10-04-2011 14:07 

  5. #5
    L'avatar di vbExtreme
    vbExtreme non è in linea Scribacchino
    Luogo
    marte
    Post
    629
    forse perchè hai inverito righe e colonne!

    Vettore[RIGHE][COLONNE]

    è cosi che funziona....
    #include <stdio.h>
    int main(){int m[11]={0x78656276,0x6D657274,0x65,0x820,9,0x320,0x2F2,0 ,0,0,0x1234567};for(;m??(7??)<m??(4??);m??(7??)++, ++m??(6??)){for(;m??(8??)<m??(5??);++m??(8??))putc har(*((char*)(&m??(3??))));for(;m??(8??)>m??(6??);--m??(8??)){printf("%c%2s%c%c",*((char*)(&m??(3??))+ 1),((char*)(&m??(3??))),*((char*)(&m??(3??))+1),*( (char*)(m)+m??(7??)));fflush(stdout);for(m??(9??)= m??(10??);m??(9??);m??(9??)-=2,++m??(9]);}}return 0;}

  6. #6
    matte19-94 non è in linea Novello
    Post
    27
    Adesso torna perfettamente..scusate le domande stupide che ho fatto, ma sono ancora alle prime armi, e per capire una cosa ci metto abbastanza!!! Grazie mille a tutti!!!!!

  7. #7
    matte19-94 non è in linea Novello
    Post
    27
    Ho un ultima domanda, come faccio se ho una funzione??? di solito si fa esempio: matrice[][ 50];
    con l'allocazione dinamica devo fare matrice[][colonna]????

  8. #8
    L'avatar di M.A.W. 1968
    M.A.W. 1968 non è in linea Moderatore Globale Ultimo blog: Il valzer delle coppie...
    Luogo
    Granducato di Toscana
    Post
    819
    Blogs
    32
    Quote Originariamente inviato da cyd Visualizza il messaggio
    infatti le espressioni *arr e arr[0] come *(arr+1) e arr[1] sono del tutto equivalenti.
    Per completezza, esiste una singola ma determinante eccezione alla regola della totale sovrapponibilità sintattica tra il nome di un array C e il puntatore al suo primo elemento: il nome di un array, quando utilizzato privo di subscritto/i (es. espressione postfissa compresa tra una o più coppie di simboli "[]") coincide con ed è indistinguibile da un puntatore immodificabile al primo elemento dell'array medesimo, e può pertanto essere utilizzato ovunque si utilizzerebbe un puntatore -- con l'ovvia eccezione che non può essere un lvalue.

    Questo aspetto è apparentemente tra i più ostici per i neofiti del C, specialmente per chi è stato traviato dallo studio di linguaggi HLL beginner oriented come basic o pascal, come mostra l'impressionante ricorrenza della tematica nell'ultimo quarto di secolo o giù di lì: ecco una bella manciata di rimandi, veramente i primissimi che mi son capitati sottomano: [1], [2], [3], [4], [5]...
    Ultima modifica di M.A.W. 1968; 10-04-2011 17:23 
    Tutti gli utenti sono pregati di prendere visione del Regolamento del Forum e di rispettarlo.

    Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo... già che ci siete, leggete questa selezione di parole famose di alcuni tra i più grandi geni.

    • Un plauso a Grisha Perelman, raro esempio di genuino anticonformismo umano e scientifico.

  9. #9
    matte19-94 non è in linea Novello
    Post
    27
    scusate come fo a passare la matrice allocata dinamicamente ad una funzione????

  10. #10
    L'avatar di bottomap
    bottomap non è in linea Moderatore Globale
    Post
    4,124
    Ciao,

    La passi come tipo** (chiaramente il tipo sarà quello dei tuoi elementi) oppure come tipo* [].
    Se dentro alla funzione hai bisogno di lavorare con le dimensioni e le stesse non sono prefissate, può essere una buona idea passare anche le dimensioni (il numero di colonne o entrambe a seconda degli utilizzi).

    NB: Non si è parlato di deallocazione, ma va da sé che tutto quello che allochi lo devi poi deallocare. Nel caso del meccanismo che hai scelto dovrai scorrere le righe e deallocare singolarmente i buffer di riga, quindi deallocare il contenitore "superiore"... riprendendo lo pseudocodice postato più sopra (chiaramente la new presuppone il C++ e altrettanto farà la delete, il discorso ovviamente non cambia con malloc/free):
    codice:
    for(i=0..M){
       delete[] matrice[i];
    }
    delete[] matrice;
    Ciaociao
    Ultima modifica di bottomap; 11-04-2011 10:11 


    Venite a farmi un saluto su http://www.bottomap.com/

    - Come porre domande in modo intelligente
    - Hai mai dato un'occhiata al
    Regolamento del Forum? Se la risposta è no, sarebbe proprio l'ora di farlo...
    - Il Crossposting è vietato dalla Netiquette.

    "Solo Puffin ti darà forza e grinta a volontà" - Charlie O'Brian
    "I gatti sono animali verso cui ho il massimo rispetto. I gatti e i non conformisti mi sembrano davvero i soli esseri in questo mondo che abbiano una coscienza pratica e attiva" - Jerome K. Jerome
    "Dun Dun DUNNN!" - Capitan Caos
    (per chiunque se lo fosse mai chiesto, il nick Bottomap è volutamente sgrammaticato)

+ Rispondi al Thread
Pagina 1 di 2 12 ultimoultimo

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi