array 2D & puntatori

Pubblicità

toni1705

Nuovo Utente
Messaggi
98
Reazioni
9
Punteggio
28
Ciao ragazzi
sto facendo un piccolo esercizio in cui mi è richiesto di inizializzare & allocare dinamicamente una variabile che dovrà poi essere passata ad una funzione
C:
// SCRITTO IN C

// variabile da allocare e inizializzare

double** A;

ho provato cosi;
Codice:
    // inizializzo la matrice
// i parametri m e n sono stati presi in input con una scanf
// generalmente avrei fatto cosi con una variabile di tipo *a
A=(double) calloc(m,sizeof(double));
// questo userebbe memoria solo per le righe
   // mi era sorto il dubbio di dover fare anche cosi per  le colonne  ma non andrebbe a sovrascrivere il valore stesso? come posso allocare un array 2d allora?
 A=(double) calloc(n,sizeof(double));

// ciclo for che scorre le righe
// ciclo for che scorre le colonne (ciclo interno)
 scanf("%lf",&A[i][j];
//lo scanf poi andrebbe cosi?
    }
 
dovresti allocare tanto spazio quanto occorre per il totale numero di elementi per la matrice, ma non funzionerebbe lo stesso in quanto per funzionare il compilatore deve sapere almeno una delle dimensioni della matrice.
Quindi il problema non è “passare il parametro a una funzione” bensì “come allocare dinamicamente una matrice”. Sono cose ben diverse.
Diciamo pure che le matrici sono un caso particolare di vettori, vanno bene per allocazioni statiche di memoria, ma per allocazioni dinamiche occorre usare altri tipi di dati. Sono cose che si dovrebbe insegnare subito a scuola.
 
Il primo errore è il cast a double, ricorda che calloc restituisce un puntatore alla memoria allocata (quindi non devi castarlo come double).
Il secondo errore è il modo in cui allochi le colonne: l'allocazione devi farla per ciascuna riga (quindi dentro il primo ciclo for).

Ps. anticipato da Andretti, comunque concordo anche con quanto dice.
 
dovresti allocare tanto spazio quanto occorre per il totale numero di elementi per la matrice, ma non funzionerebbe lo stesso in quanto per funzionare il compilatore deve sapere almeno una delle dimensioni della matrice.
Quindi il problema non è “passare il parametro a una funzione” bensì “come allocare dinamicamente una matrice”. Sono cose ben diverse.
Diciamo pure che le matrici sono un caso particolare di vettori, vanno bene per allocazioni statiche di memoria, ma per allocazioni dinamiche occorre usare altri tipi di dati. Sono cose che si dovrebbe insegnare subito a scuola.
Il primo errore è il cast a double, ricorda che calloc restituisce un puntatore alla memoria allocata (quindi non devi castarlo come double).
Il secondo errore è il modo in cui allochi le colonne: l'allocazione devi farla per ciascuna riga (quindi dentro il primo ciclo for).

Ps. anticipato da Andretti, comunque concordo anche con quanto dice.

C:
int m, n,i,j;
    double** A;
    double* x,*b;

    printf("inserire dimensione righe: ");
    scanf_s("%d", &m);

    printf("inserire dimensione colonne: ");
    scanf_s("%d", &n);
   
    // inizializzo la matrice
    A = malloc(sizeof(double*) * m);
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            A[i] = (double*)malloc(n * sizeof(double));
            //return a;  
        }
    }
    // inserisco i valori nella matrice
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
           
            A[i][j] = 10 * i + j;// valori  random xD
        }
    }
    //stampo la matrice
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            printf(" a[%lf][%lf]:%lf",i,j,A[i][j]);
            //return a;
        }
        printf("\n");
    }

    x = (double*)calloc(n, sizeof(double));
    printf("inserire vettore x ");

    for (i = 1; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
        {
            x[i] = i+1 ;
            printf("\n x[%lf]:%d",i, x[i]);
        }
    }
    b = (double*)calloc(n, sizeof(double));
    b=pmatrice(A, m, n, x); // p matrice nome funzione esterna

    for (i = 0; i < m; i++)
    {
   
       
           
            printf("\n b[%lf]:%d", i, b[i]);
       
    }
}
cosi? non capisco perchè le colonne devono essere inserite cosi..
 
No, il tuo codice è sbagliato.
In pratica la tua variabile A è un vettore di puntatori, che è la maniera classica di implementare una matrice multidimensionale dinamica.
Quindi la prima malloc() è corretta, ossia allochi un vettore di puntatori (di dimensione ‘righe’). Dopodiché devi allocare ogni elemento di tale vettore come un vettore di dimensione ‘colonne’, ossia ti basta un ciclo, mentre invece tu ne fai due (e crei così un bel memory leak).
Il secondo passo, dove inizializzi i valori della matrice, è corretto (anche se i valori non sono ‘random’).
Il passo successivo è anche corretto, anche se stampi numeri interi usando un formato ‘lf’ (ossia double), che manderà in crash un sacco di compilatori.
Mi sono fermato a quel punto.
 
No, il tuo codice è sbagliato.
In pratica la tua variabile A è un vettore di puntatori, che è la maniera classica di implementare una matrice multidimensionale dinamica.
Quindi la prima malloc() è corretta, ossia allochi un vettore di puntatori (di dimensione ‘righe’). Dopodiché devi allocare ogni elemento di tale vettore come un vettore di dimensione ‘colonne’, ossia ti basta un ciclo, mentre invece tu ne fai due (e crei così un bel memory leak).
Il secondo passo, dove inizializzi i valori della matrice, è corretto (anche se i valori non sono ‘random’).
Il passo successivo è anche corretto, anche se stampi numeri interi usando un formato ‘lf’ (ossia double), che manderà in crash un sacco di compilatori.
Mi sono fermato a quel punto.
C:
 A = malloc(sizeof(double*) * m);
    for (i = 0; i < m; i++)
    {
        for (j = 0; j < n; j++)
        {
            A[i] = (double*)malloc(n * sizeof(double));
            //return a; 
        }
    }
questo deve diventare questo-->
C:
 A = malloc(sizeof(double*) * m);
    for (i = 0; i < m; i++)
    {
        
            A[i] = (double*)malloc(n * sizeof(double));
            //return a;
    }
vabbè per i valori random ( li ho chiamati cosi per far capire che erano stati scritti senza un valido motivo in quel modo)
la stampa del double finale mi sono confuso nella fretta penso sempre agli int XD
 
Non era più semplice fare un vettore grande n*m e quindi vedere la matrice come un Array monodimensionale? La traccia lo permette?
 
Il primo errore è il cast a double, ricorda che calloc restituisce un puntatore alla memoria allocata (quindi non devi castarlo come double).
Il secondo errore è il modo in cui allochi le colonne: l'allocazione devi farla per ciascuna riga (quindi dentro il primo ciclo for).
Sono d'accordo con @DispatchCode. Le colonne vanno allocate dentro in un ciclo for. Lo dimostri dopo @toni1705. Diverso sarebbe stato se tu avessi allocato delle una matrice di stringhe allora andava usato il triplo puntatore: char ***A;
 
Ultima modifica:
Pubblicità
Pubblicità
Indietro
Top