Equivalente realloc in c++ con new e delete

di il
9 risposte

Equivalente realloc in c++ con new e delete

Salve,
ho difficoltà a fare l'equivalente della realloc in c++. Il prof suggerisce di usare un puntatore intermedio, che rialloca la nuova memoria e poi spostare il contenuto dalla vecchia, che infine viene liberata.

Qualcuno potrebbe fornirmi un esempio scritto in codice? vi ringrazio

9 Risposte

  • Re: Equivalente realloc in c++ con new e delete

     vetPtrR = new (nothrow) int[(n_elem+3) * sizeof(int)];
        if (vetPtrR == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        }
        for(i=0;i<n_elem+3;i++){
            /* vetPtrR[i]=vetPtr[i]; */
            *(vetPtrR+i)=*(vetPtr+i);
        }
        delete[]vetPtr;
    
    Ho risolto così e sembra funzionare. C'è qualcosa da migliorare?
  • Re: Equivalente realloc in c++ con new e delete

    Ciao, posta un codice compilabile in cui sia presente un esempio di utilizzo di questa realloc "fatta in casa" e potrò dirti se c'è qualcosa da migliorare.
  • Re: Equivalente realloc in c++ con new e delete

    In C++ è consigliabile usare la classe vector. Di default gestisce la dimensione in memoria automaticamente, ma puoi intervenire manualmente e in modo più sicuro tramite i metodi resize, reserve e shrink_to_fit, per usare solo la memoria che ti serve.

    https://en.cppreference.com/w/cpp/container/vecto
  • Re: Equivalente realloc in c++ con new e delete

    1) crei il nuovo array con la nuova lunghezza
    2) copi il contenuto del vecchio array nel nuovo TENENDO CONTO delle lunghezze dei due array (PIU' lungo, PIU' corto, UGUALE)
    3) getti via il vecchio array

    "vector" e' utile, MA l'esercizio e' realizzare un CLONE della "realloc" con new/delete !
  • Re: Equivalente realloc in c++ con new e delete

    Non avevo mica capito che facesse parte della traccia. Comunque la new non ha bisogno di moltiplicare per la dimensione.
    
    vetPtrR = new (nothrow) int[n_elem+3]
    
    Per accedere all'elemento non serve dereferenziare il puntatore, puoi farlo come faresti con l'array statico:
    
    vetPtrR[i] = vetPtr[i];
    
  • Re: Equivalente realloc in c++ con new e delete

    Nippolo ha scritto:


    Ciao, posta un codice compilabile in cui sia presente un esempio di utilizzo di questa realloc "fatta in casa" e potrò dirti se c'è qualcosa da migliorare.
    #include <iostream>
    #include <cstdlib> // stdlib.h libreria per il C
    
    #define MIN_NUM		-100
    #define MAX_NUM		100
    
    #define OK		0
    #define NO_MEM	-1
    
    using namespace std;
    void print_matrix(const int * v, int n_elem);
    void libera_memoria(void * ptr);
    
    int main() {
        int * vetPtr = NULL;
        int * vetPtrR = NULL;
        int n_elem, i;
        do {
            cout << "Inserire il numero di elementi del vettore: ";
    
            cin >> n_elem;
    
            if (n_elem <= 0)
                cerr << "Il numero inserito (" << n_elem << ") deve essere > 0" << endl;
        }
        while (n_elem <= 0);
    
        /* sostituire la malloc -> new
        vetPtr = (int *) malloc(n_elem * sizeof(int));
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        } */
        vetPtr = new (nothrow) int[n_elem * sizeof(int)];
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        }
    
        for (i = 0; i < n_elem; i++) {
            vetPtr[i] = MIN_NUM + ((int)rand() % (MAX_NUM - MIN_NUM + 1));
        }
    
        cout << "Vettore creato: ";
        print_matrix(vetPtr, n_elem);
    
        /* sostituire la realloc -> ?
        vetPtr = (int *) realloc(vetPtr, (n_elem + 3) * sizeof(int));
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile re-allocare " << n_elem + 3 << " elementi" << endl;
            return NO_MEM;
        } */
        vetPtrR = new (nothrow) int[(n_elem+3) * sizeof(int)];
        if (vetPtrR == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        }
        for(i=0;i<n_elem+3;i++){
            /* vetPtrR[i]=vetPtr[i]; */
            *(vetPtrR+i)=*(vetPtr+i);
        }
        delete[]vetPtr;
    
        cout << "Vettore re-creato: ";
        print_matrix(vetPtrR, n_elem + 3);
        /*free(vetPtr);
        vetPtr = NULL;*/
        //libera_memoria(vetPtr);
        delete[] vetPtrR;
        return OK;
    }
    
    void print_matrix(const int * v, int n_elem) {
        for (int i = 0; i < n_elem; i++) {
            cout << v[i];
            if (i < n_elem - 1) cout << " ";
            else cout << endl;
        }
    }
    
    void libera_memoria(void * ptr) {
        free(ptr);
        ptr = NULL;
    }
    
    
    
  • Re: Equivalente realloc in c++ con new e delete

    JosepH2OW ha scritto:


    
       
        vetPtr = new (nothrow) int[n_elem * sizeof(int)];  <========  NO
    
    
    si scrive
    
    int* p = new int[N];
    

    con 8-64 (o piu') GB di ram e' impossibile che non ci sia abbastanza memoria per allocare un vettore di 4 elementi messi in croce.

    I test se l'allocazione e' fallita sono INUTILI.
  • Re: Equivalente realloc in c++ con new e delete

    migliorabile ha scritto:


    JosepH2OW ha scritto:


    
       
        vetPtr = new (nothrow) int[n_elem * sizeof(int)];  <========  NO
    
    
    si scrive
    
    int* p = new int[N];
    

    con 8-64 (o piu') GB di ram e' impossibile che non ci sia abbastanza memoria per allocare un vettore di 4 elementi messi in croce.

    I test se l'allocazione e' fallita sono INUTILI.
    grazie. quindi devo eliminare sizeof. Il puntatore posso definiro prima?
  • Re: Equivalente realloc in c++ con new e delete

    JosepH2OW ha scritto:


    Nippolo ha scritto:


    Ciao, posta un codice compilabile in cui sia presente un esempio di utilizzo di questa realloc "fatta in casa" e potrò dirti se c'è qualcosa da migliorare.
    #include <iostream>
    #include <cstdlib> // stdlib.h libreria per il C
    
    #define MIN_NUM		-100
    #define MAX_NUM		100
    
    #define OK		0
    #define NO_MEM	-1
    
    using namespace std;
    void print_matrix(const int * v, int n_elem);
    void libera_memoria(void * ptr);
    
    int main() {
        int * vetPtr = NULL;
        int * vetPtrR = NULL;
        int n_elem, i;
        do {
            cout << "Inserire il numero di elementi del vettore: ";
    
            cin >> n_elem;
    
            if (n_elem <= 0)
                cerr << "Il numero inserito (" << n_elem << ") deve essere > 0" << endl;
        }
        while (n_elem <= 0);
    
        /* sostituire la malloc -> new
        vetPtr = (int *) malloc(n_elem * sizeof(int));
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        } */
        vetPtr = new (nothrow) int[n_elem * sizeof(int)];
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        }
    
        for (i = 0; i < n_elem; i++) {
            vetPtr[i] = MIN_NUM + ((int)rand() % (MAX_NUM - MIN_NUM + 1));
        }
    
        cout << "Vettore creato: ";
        print_matrix(vetPtr, n_elem);
    
        /* sostituire la realloc -> ?
        vetPtr = (int *) realloc(vetPtr, (n_elem + 3) * sizeof(int));
        if (vetPtr == NULL) {
            cerr << "Non è stato possibile re-allocare " << n_elem + 3 << " elementi" << endl;
            return NO_MEM;
        } */
        vetPtrR = new (nothrow) int[(n_elem+3) * sizeof(int)];
        if (vetPtrR == NULL) {
            cerr << "Non è stato possibile allocare " << n_elem << " elementi" << endl;
            return NO_MEM;
        }
        for(i=0;i<n_elem+3;i++){
            /* vetPtrR[i]=vetPtr[i]; */
            *(vetPtrR+i)=*(vetPtr+i);
        }
        delete[]vetPtr;
    
        cout << "Vettore re-creato: ";
        print_matrix(vetPtrR, n_elem + 3);
        /*free(vetPtr);
        vetPtr = NULL;*/
        //libera_memoria(vetPtr);
        delete[] vetPtrR;
        return OK;
    }
    
    void print_matrix(const int * v, int n_elem) {
        for (int i = 0; i < n_elem; i++) {
            cout << v[i];
            if (i < n_elem - 1) cout << " ";
            else cout << endl;
        }
    }
    
    void libera_memoria(void * ptr) {
        free(ptr);
        ptr = NULL;
    }
    
    
    
    Io farei qualcosa del genere:
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    typedef int T;
    
    T* my_realloc(T *old_ptr, const unsigned int old_size, const unsigned int new_size)
    {
        T *new_ptr = nullptr;
        if(old_ptr && old_size && new_size)
        {
            if(new_ptr = new(nothrow)T[new_size])
            {
                memcpy(new_ptr, old_ptr, sizeof(T) * min(old_size, new_size));
                delete[] old_ptr;
            }
        }
        return new_ptr;
    }
    
    void print_array(T *v, const unsigned int dim)
    {
        for(unsigned int i = 0; i < dim; ++i)
        {
            cout << v[i] << " ";
        }
        cout << endl;
    }
    
    int main()
    {
        unsigned int dim_1 = 3;
        unsigned int dim_2 = 8;
        unsigned int dim_3 = 6;
        T *v = new T[dim_1];
        for(unsigned int i = 0; i < dim_1; ++i)
        {
            v[i] = i + 1;
        }
        print_array(v, dim_1);
        v = my_realloc(v, dim_1, dim_2);
        print_array(v, dim_2);
        v = my_realloc(v, dim_2, dim_3);
        print_array(v, dim_3);
    }
Devi accedere o registrarti per scrivere nel forum
9 risposte