Equivalente realloc in c++ con new e delete

di JosepH2OW il
9 risposte
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

  •  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?
  • 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.
  • 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
  • 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 !
  • 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];
    
  • 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;
    }
    
    
    
  • 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.
  • 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?
  • 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