CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jun 2006
    Posts
    40

    Question 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);
    }

  2. #2
    Join Date
    Jul 2002
    Posts
    2,543

    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.

  3. #3
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: delete element from vector

    Quote Originally Posted by jwspring View Post
    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.

  5. #5
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: delete element from vector

    Quote Originally Posted by Lindley View Post
    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

  7. #7
    Join Date
    Jun 2006
    Posts
    40

    Re: delete element from vector

    Thanks to all of you!!!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured