Visualizzazione dei risultati da 1 a 10 su 15

Hybrid View

  1. #1
    Si ha ragione, mi sono espresso male, ho modificato il messaggio.
    Ecco è questo il problema, l'allocazione dinamica con malloc... pur avendo visto diversi esempi sul libro e su internet non mi è proprio chiaro come essa funzioni, e da dove devo partire innanzitutto!

  2. #2
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Quote Originariamente inviata da DaemonDestroyer Visualizza il messaggio
    Si ha ragione, mi sono espresso male, ho modificato il messaggio.
    Ecco è questo il problema, l'allocazione dinamica con malloc... pur avendo visto diversi esempi sul libro e su internet non mi è proprio chiaro come essa funzioni, e da dove devo partire innanzitutto!
    In C++ puoi anche usare new e delete (o new[] e delete[]).

    In ogni caso malloc ritorna un puntatore a un blocco di memoria che ha dimensione in bytes pari all'unico argomento della funzione:
    codice:
    void *p_blocco = malloc(n);
    p_blocco è un puntatore a un blocco di memoria di n bytes.
    Per essere utile tuttavia bisogna fare alcune considerazioni:

    sizeof ritorna le dimensioni in bytes dell'argomento:
    ad esempio sizeof(char) ritornerà sempre 1, sizeof(type *) ritorna le dimensioni in bytes di un puntatore (8 su 64bit, 4 su 32bit, 2 su 16bit)

    dunque sizeof(tipo) ti da il numero di byte di un elemento, moltiplichi questo per il numero degli elementi e ottieni il numero di byte del blocco.

    per utilizzare il blocco alla fine ti serve un cast al puntatore di tipo.

    Ad esempio per allocare un array di interi di n elementi servirà
    codice:
    int *array = (int *)malloc( sizeof(int) * n );
    Ti allego la soluzione dell'esercizio che è un esempio di allocazione dinamica:
    codice:
    #include <iostream>
    #include <fstream>
    
    //necessario se usi malloc e free, non necessario altrimenti
    #include <cstdlib>
    
    using namespace std;
    
    int **readMat(int**&m, size_t& size, ifstream& in) {
        in >> size;
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                in >> m[i][j];
        return m;
    }
    
    int **readMat1(int **&m, size_t& size, ifstream &in) {
        in >> size;
        m = (int **)malloc(sizeof(int *) * size);
        for(int i = 0; i < size; ++i)
            m[i] = (int *)malloc(sizeof(int) * size);
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                in >> m[i][j];
        return m;
    }
    
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
    }
    
    void freeMat1(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            free(m[i]);
        free(m);
    }
        
    int main(void) {
        ifstream in("input.txt");
        size_t size;
        int **m;
        readMat1(m, size, in);
        for(int i = 0; i < size; ++i) {
            for(int j = 0; j < size; ++j)
                cout << m[i][j] << '\t';
            cout << endl;
        }
        freeMat1(m, size);
        return 0;
    }
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  3. #3
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Da notare infine che puoi allocare un unico blocco di memoria e calcolare gli indici. Prova a pensare tu come.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  4. #4
    Grazie mille Scara, la tua risposta è stata più che soddisfacente! Finalmente le idee mi sono già più chiare, e finalmente ho capito, grazie al cast di cui mi hai parlato, a cosa erano dovuti quegli errori che spesso mi dava Dev c++. Analizzerò per bene il programma che mi hai fornito e tenterò di rifarlo da solo, proverò altresì ad allocare un unico blocco di memoria. Se dovessi riuscirci posterò il mio risultato qui!

  5. #5
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Nessun problema. Nota che io ti ho offerto 2 coppie di funzioni in ogni caso: una usa malloc e free, l'altra new e delete.
    Se c'è qualcosa che non capisci chiedi pure (:
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  6. #6
    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Nessun problema. Nota che io ti ho offerto 2 coppie di funzioni in ogni caso: una usa malloc e free, l'altra new e delete.
    Se c'è qualcosa che non capisci chiedi pure (:
    Ciao scara! Il tuo programma funziona correttamente, ho preferito utilizzare le funzioni con new int e delete che, a mio parere, sono più semplici da ricordare e da scrivere. Ho continuato il programma, ora è a buon punto, ho aggiunto una funzione che mi calcola l'indice minimo nelle colonne, te lo faccio vedere



    codice:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    
    
    using namespace std;
    
    
    int **readMat(int**&m, size_t& size) 
    {
    	ifstream in("mat.txt");
        in >> size;
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
        for(int i = 0; i < size; ++i)
            for(int j = 0; j < size; ++j)
                in >> m[i][j];
        return m;
    }
    
    
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
    }
    
    
    int   calc_ind_min(int **&m,int size,int r)
    {
    	int min=m[r][0];
    	int i,indmin=0;
    	for (i=0;i<size;i++)
    	{
          if (m[r][i]<min)
          {
          	min=m[r][i];
          	indmin=i;
          }
    	}
    	cout<<indmin;
    	return indmin;
    }
    
    
    int main(void) {
        size_t size;
        int **m;
        readMat(m, size);
        for(int i = 0; i < size; ++i) {
            for(int j = 0; j < size; ++j)
                cout << m[i][j] << '\t';
            cout << endl;
        }
        int r;
        for(r=0;r<size;r++)
    	{
    		calc_ind_min(m,size,r);
        }
        freeMat(m, size);
        return 0;
    }
    Però ti vorrei chiedere alcune cose. Nel programma mi è quasi tutto chiaro, devo solo capire, qual'è precisamente la funzione di new int? La funzione di delete è quella di liberare la memoria altrimenti si appesantisce il sistema, ma new int, prima di size nella prima funzione, a che serve precisamente?
    E poi, size_t che tipo è? Ha la stessa funzione di unsigned int? Grazie per il tuo tempo!!

  7. #7
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Un consiglio, mai eseguire istruzioni di input output all'interno di una funzione che non dovrebbe prevedere IO, come quella che hai scritto tu.
    Quindi parto con qualche correzione
    codice:
    void freeMat(int **&m, size_t size) {
        for(int i = 0; i < size; ++i)
            delete[] m[i];
        delete[] m;
        //correzione sul mio stesso codice :D anche se non strettamente necessaria
        m = NULL; //in caso di doppia deallocazione non lancia errore
    }
    
    
    int calc_ind_min(int ** m,int size,int r) //non è necessaria &, ti lascio approfondire
    {
        int min=m[r][0];
        int i,indmin=0;
        for (i=0;i<size;i++)
        {
          if (m[r][i]<min)
          {
            min=m[r][i];
            indmin=i;
          }
        }
        //meglio evitare IO all'interno di funzione non create SPECIFICATAMENTE per IO
        return indmin;
    }
    
    
    //...
        for(r=0;r<size;r++)
        {
            cout << calc_ind_min(m,size,r);
        }
    //...
    Passiamo ora a rispondere alle tue domande.
    size_t non è altro che un intero positivo che rappresenta le grandezze in bytes, è definito proprio come typedef unsigned int size_t;.
    Analizziamo la funzione per l'allocazione della matrice. In particolare, assumendo size l'ordine della matrice quadrata e m una variabile int **,
    codice:
        m = new int *[size];
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
    Per l'allocazione della matrice non la si considera come tale, ma come array di array: ad esempio la matrice
    codice:
    m
    1 2 3
    4 5 6
    7 8 9
    è rappresentata dome un array
    codice:
    m = A B C
    dove A B C sono
    codice:
    A = 1 2 3
    B = 4 5 6
    C = 7 8 9
    Perciò l'allocazione di divide in due parti: una prima parte che alloca un array di puntatori ad interi
    codice:
        m = new int *[size];
    e una parte dove ad ogni puntatore è assegnato un array di interi
    codice:
        for(int i = 0; i < size; ++i)
            m[i] = new int[size];
    La deallocazione avviene all'inverso, prima si deallocano i blocchi interni, poi quelli esterni. Qui per la precisione si parla di jagged arrays. Puoi cercare su internet.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.