Memory allocation and delete in a class

68 Views Asked by At

Having trouble with memory allocation and pointers

I'm having trouble with pointers and dynamic memory. I made a class FileReader that read from a file formated like this.

FirstName,LastName,Year,GPA

String,String,String,Integer

Chris,Knight,Fr,3.8

Mitch,Taylor,Jr,3.5

The first line, I stored it in a vector called Names

and 2nd line in vector called Types.

I also made a vector that holds void pointers since it will hold arbitrary types

My question is, how can I free up those memory in the heap?

#ifndef RECORD_H
#define RECORD_H
class Record{
private:
    //POINTER VARIABLES
    int *intPtr;
    double *doublePtr;
    vector<string*> stringPtrList;

    //NAMES,TYPES, AND VALUES
    vector<string> Names;
    vector<string> Types;
    vector<void*> Values;
public:
    Record(vector<string> _names, vector<string> _types, vector<string>_values){
        Names = _names;
        Types = _types;
        //ALOCATING MEMORY
        for (unsigned i = 0; i < Types.size(); i++){
            string *stringPtr = new string;
            stringPtrList.push_back(stringPtr);
        }
        for (unsigned int i = 0; i < Types.size(); i++){
            if (Types[i] == "Integer"){
                intPtr = new int;
                *intPtr = stoi(_values[i]);
                Values.push_back((void*)intPtr);
            }
            else if (Types[i] == "Double"){
                doublePtr = new double;
                *doublePtr = stod(_values[i]);
                Values.push_back((void*)doublePtr);
            }
            else if (Types[i] == "String"){
                *stringPtrList[i] = _values[i];
                Values.push_back((void*)stringPtrList[i]);
            }
            else{
                cout << "No match Type" << endl;
            }
        }

    }
    Record(const Record &r){
        int *intPtr = new int;
        intPtr = r.intPtr;
        double *doublePtr = new double;
        doublePtr = r.doublePtr;
        for (int i = 0; i < r.stringPtrList.size(); i++){
            stringPtrList[i] = new string;
            stringPtrList[i] = r.stringPtrList[i];
        }
    }
    ~Record(){
        delete intPtr, doublePtr;
        for (int i = 0; i < Types.size(); i++){
            delete stringPtrList[i];
        }
        cout << "Pointer are deleted" << endl;
    }
    friend ostream&operator <<(ostream &os, const Record &r){
        for (unsigned int i = 0; i < r.Types.size(); i++){
            if (r.Types[i] == "Integer"){
                os << "Integer: " << *(int*)r.Values[i] << endl;
            }
            else if (r.Types[i] == "String"){
                os << "String" << *static_cast<string*>(r.Values[i]) << endl;
            }
            else if (r.Types[i] == "Double"){
                os << "Double" << *(double*)r.Values[i] << endl;
            }
            else{
                cout << "Fatal Error!" << endl;
            }
        }
        cin.get();
        return os;
    }
};
#endif
1

There are 1 best solutions below

0
On
  1. GPA has to be a float, not an int. 3.5 can not be an int.
  2. This sounds like homework question. Even if it isn't, it sounds like you are over-complicating things. Just use a list (vector) of structs.
  3. If you really have to be able to handle any type, just use a value-pair type of stuct, something along the lines of:

    struct Record { string value; VAR_TYPE type; //this is some enum you defined. }

Keep a list of columns with types and column index, so easily process each record as you read it. Since you know the type of each record, you can cast it to that when you are actually going to use it.

It's much cleaner that way, no need for dynamic allocation (which is slow) and messing with void pointers.