Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deleting an array of pointer to struct

Tags:

c++

i have the following struct:

struct Message {
    Agent *_agent;
    double _val;
};

and the following Ptrs array:

typedef Message* MessageP;
MessageP *_msgArr;
_msgArr = new MessageP[MAX_MESSAGES];

this is the method that inserts a Message to the array:

void Timing::AddMessage(Agent * const agentPtr, double val) {

    MessageP msgPtr = new Message;
    assert(msgPtr != 0);

    //assign values:
    (*msgPtr)._agent = agentPtr;
    (*msgPtr)._val = val;

    //add to messages array:
    assert(_msgArr != 0 && _waitingMsgs<MAX_MESSAGES);
    _msgArr[_waitingMsgs] = msgPtr;
    _waitingMsgs++;

}

My question is about the deletion of this array. I would like to delete the array and all allocated structs. if i write:

delete [] _msgArr  

will this delete also each allocated struct or will free only the allocated memory for the array?

Is the correct way is to go over the entire array with a for loop and write

delete _msgArr[i]

and at last wite delete [] _msgArr to delete the allocated array ?

thanks!

like image 494
Asher Saban Avatar asked Nov 20 '25 21:11

Asher Saban


2 Answers

Yes, you need to loop over all elements and delete them manually before calling delete[] on the array.

like image 149
Alexander Gessler Avatar answered Nov 22 '25 11:11

Alexander Gessler


The delete [] will call the destructors on the struct pointers, which doesn't dispose of the structs or the _agent members, which itself points to memory. You could call delete _msgArr[i]._agent and then delete _msgArr[i] in a loop, which will dispose of the Agent and then the Message.

First, though, you need to know who should get rid of the Agents, and when. If these are owned by another data structure, you shouldn't get rid of them when getting rid of _msgArr, and looping over _delete _msgArr[i] followed by delete [] _msgarr; is all you need.

If you do need to delete the Agents also, you have three reasonable choices.

First, you can give Message a destructor that will delete its _agent. It should also have a copy constructor and assignment operator defined then, either to pass ownership or to copy, or else define them as private so any attempt to use them will be a compile-time error.

Second, you could change the Agent * to a smart pointer, so that the extra memory will be deleted when the Message goes away.

Third, you could go through the loop I suggested above when getting rid of the array.

Unless you have good reasons to keep the code C-compatible, I'd suggest that you use a std::vector<boost::shared_ptr<Message> >, and have Message contain a boost::shared_ptr<Agent> rather than an Agent * (if you don't have to dispose of the Agents, Agent * is fine). At that point, you don't need to worry: when _msgArr goes out of scope, all the memory is cleaned up properly.

like image 32
David Thornley Avatar answered Nov 22 '25 13:11

David Thornley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!