Allocazione dinamica di una matrice

di il
16 risposte

Allocazione dinamica di una matrice

Salve a tutti,

potreste fornirmi alcuni chiarimenti riguardo alla procedura per l'allocazione dinamica di una matrice?
#include <stdio.h>
#include <stdlib.h>

int main() {
	
	int **matrice; /* 1. perchè doppio puntatore?*/

	int i, j;
	int colonne, righe;

	printf("righe da allocare:\n");
	scanf("%d",&righe);

	printf("colonne da allocare:\n");
	scanf("%d",&colonne);

	matrice = (int**) malloc(righe*colonne*sizeof(int)); /*2 perchè doppio puntatore???*/

	

	for (i=0;i<righe;i++)
		matrice[i]=(int*)malloc(colonne*sizeof(int)); 	/*3 perchè matrice[i]*/


	

	for(i=0;i<righe;i++)
		for(j=0;j<colonne;j++){
			printf("Elemento: [%d] [%d]\n", i+1, j+1);
			scanf("%d",&matrice[i][j]);
		}

	

	for (i=0;i<righe;i++)
		for(j=0;j<colonne;j++)
			printf("Elemento:  [%d] [%d] : %d\n",i+1, j+1, matrice[i][j]);

	}
utilizzando il codice postato i passaggi poco chiari che riscontro sono 3:

1- per quale motivo viene inizializzato un puntatore intero ad una variabile 'matrice' con due asterischi?

2- perchè nel momento in cui alloco fisicamente lo spazio per la matrice il casting (int**) esige ancora il doppio puntatore?

3-
for (i=0;i<righe;i++)
		matrice[i]=(int*)malloc(colonne*sizeof(int)); 	/*3 perchè matrice[i]*/
è soprattutto questa la parte di codice che mi rimane meno chiara. la seconda parte della matrice, le colonne, hanno bisogno di essere riallocate sottraendo lo spazio all'allocazione totale fatta nella prima dichiarazione?

grazie mille a tutti.

Saluti.

16 Risposte

  • Re: Allocazione dinamica di una matrice

    1 - Il doppio puntatore è richiesto in quanto querllo che stai creando non è una matrice ma solamente un aray di puntatori, ogniuno dei quali punta a sua volta a una array.
    Quello che è effettivamente sbagliato è che:
    1 - Vengono allocati troppi elementi, dovrebbe allocare spazio solamente per il numero di righe
    2 - dovrebbe allocrae lo spazio per un puntatore int, ovvero sizeof(int *), e non sizeof(int)
    
    matrice = malloc(righe*sizeof(int)); 
    
    2 - Come vedi, tranne che tu stia utilizzando un compilatore C++ per compilare il tuo codice C, il cast del valore di ritorno della malloc non serve a nulla e porta solo guai, su cui non mi sembra il caso di dilungarmi ora.

    3 - Per quanto riguarda la terza domanda, correggendo l'errore descritto nella prima, è necessario allocare le colonne (gli array a cui puntano i puntatori allocati precedentemente) delle righe della matrice: quel ciclo fa esattamente quello.


    Vorrei comunque farti notare che quello che fa il tuo codice è tutto tranne che allocare una matrice: diciamo che fondamentalmetne frammenta in modo ottimale la memoria Una matrice è una "zona di memoria" contigua in cui le colonne sono ripetute per righe volte.
    Infatti una matrice allocata dinamicamente andrebbe allocata come
    
    int *matrice = malloc(righe*colonne*sizeof(int));
    
    che è probabilmente quello che stava facendo chiunque abbia scritto quel pezzo di codice sbagliato

    ancora meglio utilizzando
    
    int *test = malloc(sizeof(int[righe][colonne]));
    
    in questo modo la matrice può poi essere utilizzata facendo:
    
      for (i = 0; i < righe; ++i)
      {
          for (j = 0; j < colonne; ++j)
          {
            printf("Inserire un numero per matrice[%d][%d]", i, j);
            scanf("%d", &intMatrix[i*righe + j]);
          }
      }
      


    Come ultima cosa tieni sempre presente che malloc &b co. possono fallire l'allocazione. Nel qual caso tornano NULL invece che un indirizzo utilizzabile, quindi è mandatorio che venga controllato il valore ritornato da tali funzioni prima di utilizzarlo.
    
    int *matrice = malloc(righe*colonne*sizeof(int));
    if (matrice == NULL)
    {
       fprintf(stderr, "Allocazione fallita!!\n");
    }
    
  • Re: Allocazione dinamica di una matrice

    Ciao,

    continuo a non capire.

    la dichiarazione di array è differente.

    intendi che con i doppi asterischi posso creare un primo array, che punta ad un secondo array
    identificato da matrice?
  • Re: Allocazione dinamica di una matrice

    te_(x)_ture ha scritto:


    Ciao,

    continuo a non capire.

    la dichiarazione di array è differente.

    intendi che con i doppi asterischi posso creare un primo array, che punta ad un secondo array
    identificato da matrice?


    Ok, partiamo con una domanda semplice: sai cosa è un puntatore di puntatore?
  • Re: Allocazione dinamica di una matrice

    Scusa, non mi era comparso il post per intero quindi non avevo letto tutto.

    si. un indirizzo che identifica una parte di memoria
  • Re: Allocazione dinamica di una matrice

    Scusa ancora,

    no un puntatore di puntatore no, non so cosa significa.
  • Re: Allocazione dinamica di una matrice

    te_(x)_ture ha scritto:


    Scusa, non mi era comparso il post per intero quindi non avevo letto tutto.

    si. un indirizzo che identifica una parte di memoria
    No. è un puntatore che punta un altro puntatore che a sua volta punta un indirizzo in memoria: ti è chiaro?
  • Re: Allocazione dinamica di una matrice

    Ok. ci sono.
  • Re: Allocazione dinamica di una matrice

    te_(x)_ture ha scritto:


    Ok. ci sono.
    Bene, capito questo, il doppio asterisco, indica proprio un puntatore a puntatore.

    Il codice da te postato, come già detto prima con vari errori, in pratica alloca per prima cosa una array di puntatori, che poi punteranno a loro volta alla "memorie" allocate con il secondo for.
  • Re: Allocazione dinamica di una matrice

    Ok e concettualmente avevo capito che intendevi questo da principio.
    il punto è che non capisco come fa ad allocare un array se la sintassi per allocare un array è:

    tipo nome_array [quantità];

    o in alternativa:

    tipo nome_array = {quantita}

    altre sintassi non ho trovate per istanziare un array.
    e queste due lungo il mio codice non le vedo.
     matrice = (int**) malloc(righe*colonne*sizeof(int
    perchè questa dicitura alloca un array?
  • Re: Allocazione dinamica di una matrice

    
    tipo nome_array = {quantita}
    
    Non ha senso, mentre il tuo primo esempio lo ha.

    Detto ciò quello a cui stai facendo riferimento tu è un array "statico" ovvero allocato con una dimensione fissa.

    Il code che hai postato utilizza invece l'allocazione dinamica, ovvero, attraverso la malloc, richiedere una area di memoria contigua grande quanto il parametro passato alla malloc. Essa infine, se ha successo, ritorna l'indirizzo al primo byte del chunk di memoria allocato.
  • Re: Allocazione dinamica di una matrice

    Giusto:

    tipo nome_array = {1, 2, 3, .., n}

    quindi la malloc alloca necessariamente un array?
  • Re: Allocazione dinamica di una matrice

    Certo, alloca una dimensione di memoria grande quanto la dimensione di un parametro prefissato.
    ecco perchè richiede la specifica del tipo di dato che vi si allocherà (int, char, float)

    e quindi quello che alloca è necessariamente un array.

    detto cio con il codice da me postato non si crea una matrice ma un array di dimensione n
    dal quale con il secondo ciclo for se ne ricava il puntatore ad una zona che funge da colonna/riga.
  • Re: Allocazione dinamica di una matrice

    te_(x)_ture ha scritto:


    Giusto:

    tipo nome_array = {1, 2, 3, .., n}

    quindi la malloc alloca necessariamente un array?

    Nemmeno questa va bene
    Quello che vuoi scrivere è
    
    tipo nome_array[] = {1, 2, 3, .., n}
    
    Invece per quanto riguarda la malloc, vedi la pagina del manuale che ti ho girato: alloca n byte nella memoria da lei gestita (tipicamente in heap). L'array è solo un concetto di memoria contigua di un certo tipo indirizzabile con [ ], come lo è una struttura che contiene 10 elementi interi, d'altro canto, ma di cui non puoi scorrere gli elementi semplicemente utilizzando [ ].
  • Re: Allocazione dinamica di una matrice

    Ahahah non ne azzecco una ahaha

    scusa ma che manuale mi hai girato?
Devi accedere o registrarti per scrivere nel forum
16 risposte