array 2D & puntatori

toni1705

Nuovo Utente
98
9
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?
    }
 

Andretti60

Utente Èlite
6,440
5,091
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.
 
  • Mi piace
Reazioni: DispatchCode

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
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.
 
  • Mi piace
Reazioni: BigIssue

toni1705

Nuovo Utente
98
9
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..
 

Andretti60

Utente Èlite
6,440
5,091
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.
 
  • Mi piace
Reazioni: toni1705

toni1705

Nuovo Utente
98
9
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
 

Ibernato

Utente Èlite
4,328
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Non era più semplice fare un vettore grande n*m e quindi vedere la matrice come un Array monodimensionale? La traccia lo permette?
 

BigIssue

Utente Attivo
221
18
CPU
intel dual core n3050
Scheda Madre
asus x540s
RAM
4gb
GPU
intel HD
OS
Windows 10
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:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Non era più semplice fare un vettore grande n*m e quindi vedere la matrice come un Array monodimensionale? La traccia lo permette?

Secondo me si, ma sarà sicuramente un esercizio, visto il tipo di richiesta. Non penso abbia scelta.
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili