-
June 7th, 2011, 10:36 AM
#1
delete element from vector
Hi,
I have problem to delete element form my vector "prjs". The element includes visual control TEdit which stays on interface after I delete it. I found the reason was that the erase() didn't call destructor ~PRJNODE(); Do you know why?
Thanks in advance!
class PRJNODE
{
public:
TEdit * txtStatus;
TPopupMenu *popupMene1;
...
PRJNODE(TPanel*, TPopupMenu *);
PRJNODE();
~PRJNODE();
};
PRJNODE::PRJNODE(TPanel *frm, TPopupMenu *popup){
PRJNODE();
popupMene1=popup;
txtStatus = new TEdit(frm);
txtStatus->Parent = frm;
txtStatus->SetBounds(4, 100, 100, 20);
txtStatus->PopupMenu=popup;
};
PRJNODE::~PRJNODE(){
if (txtStatus){
txtStatus->Visible=false;
delete txtStatus; txtStatus=NULL;
}
};
typedef std::vector<PRJNODE*> PrjNodeVector;
class PRJCLS
{
public:
PrjNodeVector prjs;
void AddOnePrj();
...
};
void PRJCLS::AddOnePrj()
{
PRJNODE *newprj;
for (int i=0; i<5;i++) {
newprj=new PRJNODE(pnlTable, popup);
prjs.push_back(newprj);
}
...
for (int i=0; i<5;i++)
prjs.erase(prjs.begin()+i);
}
-
June 7th, 2011, 10:50 AM
#2
Re: delete element from vector
for (int i=0; i<prjs.size();i++)
{
delete prjs[i];
}
prjs.clear();
PRJNODE destructor is called only if vector contains PRJNODE instances. Since your vector contains PRJNODE pointers, you are responsible to delete them.
Last edited by Alex F; June 7th, 2011 at 10:52 AM.
-
June 7th, 2011, 10:50 AM
#3
Re: delete element from vector
Because you don't have a vector of PRJNODE; you have a vector of PRJNODE*. The destructor of a pointer is trivially empty.
If you had a vector of PRJNODE, then erasing an element would call its destructor (and probably invoke copy or move semantics on other elements in the vector as they are shuffled over). But you have instead chosen to use a vector of pointers, which are a primitive type.
The fact that the pointer points to a particular type is something you know. It is not something the vector knows, and if you think about it for a minute, you'd realize how terrible an idea it would be for a vector to go invoking "delete" on any pointer it happened to contain.
-
June 7th, 2011, 11:30 AM
#4
Re: delete element from vector
Originally Posted by jwspring
Hi,
I have problem to delete element form my vector "prjs". The element includes visual control TEdit which stays on interface after I delete it. I found the reason was that the erase() didn't call destructor ~PRJNODE(); Do you know why?
Code:
#include <vector>
int main()
{
std::vector<char*> p;
p.push_back("abc123");
p.erase(p.begin());
}
That piece of code should answer your question. The vector holds pointer to char. The "abc123" is a (const) char*. Should vector call delete on this when erase() is called? I didn't allocate anything, so calling delete will not work.
Second example:
Code:
#include <vector>
#include <windows.h>
int main()
{
std::vector<char*> p;
char *temp = new char[7];
p.push_back(temp);
p.erase(p.begin());
// do again, but only allocate a single char
temp = new char;
p.push_back(temp);
p.erase(p.begin());
// one more time
temp = (char *)GlobalAllocPtr(GMEM_FIXED, 1);
p.push_back(temp);
p.erase(p.begin());
}
So, we now have placed an item using new[]. But how does vector know whether to call "delete" or "delete[]" when erase() is called? If vector calls "delete", then it is calling the wrong form of delete (it should be calling "delete []"). On the second try, a single char is allocated using just "new". So how does vector know to call "delete" instead of "delete[]"? Look at the last try -- the pointer is pointing to memory created with the Windows API GlobalAllocPtr() function. How is vector to know to call GlobalFreePtr() function when vector::erase() is called?
So now you see that vector has no idea and does not care where those pointers come from or what they're pointing to. If you dynamically allocate memory, you're responsible for deallocating the memory, as vector, and basically any value-based container cannot make this decision by itself.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; June 7th, 2011 at 11:36 AM.
-
June 7th, 2011, 01:50 PM
#5
Re: delete element from vector
The exception is smart pointers. Most smart pointers assume they will need to call "delete", except for a few in boost which are designed to call delete[]. Of course, you can override the default deleter for most smart pointer implementations.
-
June 7th, 2011, 02:01 PM
#6
Re: delete element from vector
Originally Posted by Lindley
The exception is smart pointers. Most smart pointers assume they will need to call "delete", except for a few in boost which are designed to call delete[]. Of course, you can override the default deleter for most smart pointer implementations.
Smart pointers, at least as far as I know, wouldn't be considered vaule-based containers.
Regards,
Paul McKenzie
-
June 8th, 2011, 03:32 PM
#7
Re: delete element from vector
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|