C Allocazione matrice dinamica

di il
12 risposte

C Allocazione matrice dinamica

Sto studiando le matrici dinamiche, riscontro una differenza rispetto alle matrici statiche, se dichiaro una matrice statica a due dimensioni e poi uso il suo puntatore, posso esplorare tutti i valori serialmente come fosse un vettore.
La stessa cosa non succede con la matrice a due dimensioni allocata dinamicamente.
Di seguito il codice di test, alloco una matrice dinamica a due dimensioni, la riempio di numeri progressivi con due cicli e la visualizzo regolarmente.
Poi come farei con una matrice statica, inizializzo il suo puntatore e lo utilizzo per visualizzare la matrice serialmente, alla visualizzazione si capisce che le righe della matrice in memoria non sono contigue.

Sbaglio ad allocare la matrice? o quale info mi manca?

#include <stdio.h>
#include <stdlib.h>

#define DIM 6

void visualizza(int **m){

    for (int r=0; r<DIM; r++) {
        for (int c=0; c<DIM; c++) {
            printf("%02d ", m[r][c]);
        }
        printf("\n");
    }
}

int main(){

    int **dinamica;
    dinamica=(int **)malloc(sizeof(int *)*DIM);
    for(int r=0; r<DIM; r++)
        dinamica[r]=(int *)malloc(sizeof(int)*DIM);

    /* riempio con tabellina dell'uno */
    for(int r=0; r<DIM; r++)
        for(int c=0; c<DIM; c++)
            dinamica[r][c]=(c+1)+r*DIM;
    visualizza(dinamica); // visualizzo

    int *d=*dinamica; // puntatore all'inizio della matrice

    // visualizzo seriale
    printf("\n");
    for (int i=0; i<DIM*DIM; i++)
        printf("%02d ",d[i]);
   
    // dealloco
    for (int r=0; r<DIM; r++)
        free(dinamica[r]);
    free(dinamica);
    return 0;
}

12 Risposte

  • Re: C Allocazione matrice dinamica

    Qui io ho sempre visto un po' di confusione


    Magari seguendo è la volta che capisco anch'io


    Quello che hai fatto secondo me non è allocare una matrice, né dinamica ne statica, ma allocare 'prima' un'area di memoria per contenere un gruppo di puntatori
    Poi inizializzare questi puntatori a puntare su tante aree di memoria separate che contengono tanti vettori separati


    Stasera dal pc e con la tastiera vera, provo a spiegarmi meglio
  • Re: C Allocazione matrice dinamica

    Dai un'occhiata a questo

    http://www.ce.uniroma2.it/courses/ce1819/slides/C_matrici_alloc_din.pdf
  • Re: C Allocazione matrice dinamica

    Non mi si apre...


    Correggo, sì è aperta
  • Re: C Allocazione matrice dinamica

    StandardOil ha scritto:


    Qui io ho sempre visto un po' di confusione


    Magari seguendo è la volta che capisco anch'io


    Quello che hai fatto secondo me non è allocare una matrice, né dinamica ne statica, ma allocare 'prima' un'area di memoria per contenere un gruppo di puntatori
    Poi inizializzare questi puntatori a puntare su tante aree di memoria separate che contengono tanti vettori separati


    Stasera dal pc e con la tastiera vera, provo a spiegarmi meglio
    Si, i puntatori che puntano ad altri puntatori sono allocati in memoria in un vettore... mi chiedevo se i puntatori puntati potessero puntare a zone che poi risultino contigue, magari con un ulteriore calcolo dello spazio occupato dalla riga, anche fosse un po' complesso scrivere una routine generica, poi è per sempre. Ma forse sto dicendo delle baggianate
    Si fa prima ad allocare un vettore e poi ad usarlo come fosse a più dimensioni.
    Ora mi leggo il link di oregon
  • Re: C Allocazione matrice dinamica

    oregon ha scritto:


    Dai un'occhiata a questo

    http://www.ce.uniroma2.it/courses/ce1819/slides/C_matrici_alloc_din.pdf
    E' a dir poco illuminante, letto e capito, grazie.
    Il codice corretto con le nuove info, le spiegazioni al link di oregon: http://www.ce.uniroma2.it/courses/ce1819/slides/C_matrici_alloc_din.pdf
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define DIM 6
    
    void visualizza(int **m){
    
        for (int r=0; r<DIM; r++) {
            for (int c=0; c<DIM; c++) {
                printf("%02d ", m[r][c]);
            }
            printf("\n");
        }
    }
    
    int main(){
    
        int **dinamica;
        dinamica = (int **)malloc(DIM*sizeof(int *));
        dinamica[0] = (int*)malloc(DIM*DIM*sizeof(int));
        for (int i=1; i<DIM; i++)
            dinamica[i] = dinamica[0] + i*DIM;
    
        /* riempio con tabellina dell'uno */
        for(int r=0; r<DIM; r++)
            for(int c=0; c<DIM; c++)
                dinamica[r][c]=(c+1)+r*DIM;
        visualizza(dinamica); // visualizzo
    
        int *d=*dinamica; // puntatore all'inizio della matrice
    
        // visualizzo seriale
        printf("\n");
        for (int i=0; i<DIM*DIM; i++)
            printf("%02d ",d[i]);
    
        // dealloco
        for (int r=0; r<DIM; r++)
            free(dinamica[r]);
        free(dinamica);
        return 0;
    }
    
  • Re: C Allocazione matrice dinamica

    @Rubik occhio alla deallocazione.
  • Re: C Allocazione matrice dinamica

    Nippolo ha scritto:


    @Rubik occhio alla deallocazione.
    ops non l'ho neanche guardato.
    Devo deallocare a ritroso quello che ho allocato, così è giusto?
    
        // dealloco
        for (int r=1; r<DIM; r++)
            free(dinamica[r]);
        free(dinamica[0]);
        free(dinamica);
    
  • Re: C Allocazione matrice dinamica

    Scusa ma il numero delle free() non dovrebbe coincidere con quello delle malloc()?
  • Re: C Allocazione matrice dinamica

    Nippolo ha scritto:


    Scusa ma il numero delle free() non dovrebbe coincidere con quello delle malloc()?
    Considera che sto facendo il ragionamento ora
    le allocazioni:
    
        dinamica = (int **)malloc(DIM*sizeof(int *));
        dinamica[0] = (int*)malloc(DIM*DIM*sizeof(int));
    
    le deallocazioni:
    
        free(dinamica[0]);
        free(dinamica);
    
    nel for non c'è più malloc ho sbagliato.
    ma ti chiedo conferma, perché l'unica cosa sicura che ho imparato del C, è che non c'è niente di scontato.
  • Re: C Allocazione matrice dinamica

    Rubik ha scritto:


    ma ti chiedo conferma, perché l'unica cosa sicura che ho imparato del C, è che non c'è niente di scontato.
    Così dovrebbe andare. D'altronde lo standard recita:
    The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.
  • Re: C Allocazione matrice dinamica

    Rubik ha scritto:


    Si, i puntatori che puntano ad altri puntatori sono allocati in memoria in un vettore... mi chiedevo se i puntatori puntati potessero puntare a zone che poi risultino contigue, magari con un ulteriore calcolo dello spazio occupato dalla riga, anche fosse un po' complesso scrivere una routine generica, poi è per sempre. Ma forse sto dicendo delle baggianate
    Si fa prima ad allocare un vettore e poi ad usarlo come fosse a più dimensioni.
    Ora mi leggo il link di oregon
    Le righe sono allocate mediante delle malloc indipendenti, l'allocatore non ha motivo di rendere ognuna di esse contigua alla precedente.
  • Re: C Allocazione matrice dinamica

    Nippolo ha scritto:


    The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

    Alexv ha scritto:


    Le righe sono allocate mediante delle malloc indipendenti, l'allocatore non ha motivo di rendere ognuna di esse contigua alla precedente.
    Grazie ad entrambi.
Devi accedere o registrarti per scrivere nel forum
12 risposte