Thread: std::list question

  1. #1
    Registered User
    Join Date
    Oct 2003
    Posts
    5

    Question std::list question

    hi,

    i want to use a stl list of pointers in my program, so i made a little test application to find out exactly how much "maintenance" i need to perform on them (after removing them from the list). however, the behavior of the program has got me a little confused. the code below gives no errors (as i thought it would):

    Code:
    #include <list>
    #include <iostream>
    using namespace std;
    
    class dummy
    {
    public:
    	dummy() {};
    	~dummy() { cout << "destructor" << endl; }
    
    	void blah() { cout << "blah" << endl; }
    };
    
    int main()
    {
    	list<dummy*> theList;
    	list<dummy*>::iterator it;
    
    	dummy *a = new dummy();
    	dummy *b = new dummy();
    	theList.push_back(a);
    	theList.push_back(b);
    
    	cout << theList.size() << endl;
    
    	for (it = theList.begin(); it != theList.end(); it++)
    	{
    		(*it)->blah();
    	}
    
    	theList.remove(a);
    
    	delete a;
    	a = NULL;
    	a->blah();
    
    	return 0;
    }
    it seems to me that the last a->blah() call should throw an access violation, yet it works fine (i even checked, and the destructor is being called like it should be on the delete a; line). can anyone tell me what's going on here? and what clean up i will need to worry about when handling a list of pointers? thanks!

  2. #2
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    a->blah() is undefined behaviour, that includes actually working. Since dummy has no actual data members there is nothing to acess and therefore violate. The normal expected (but not defined) behavior of methods on a pointer to a deleted object is to go ahead and use all the memory it was using before, regardless of wether or not it makes any sence to do so. NULL just happens to be a memory location that it's easy for the hardware to inform the operating system that your program no longer knows what the hell it's doing, but c++ no longer cares, it's undefined.

    As far as containers of pointers to dynamic memory, it's genrally not worth it. Make your copy ctor as cheap as posible or if it's a real problem use boost::shared_ptr.

  3. #3
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Using a pointer after a call to delete is effectively undefined....it may crash...it may not, but if you want reliable code, you wont take the risk.

    As to using pointers as part of a container....I dislike doing this as it's cumbersome and often error prone......my preference is to either allow the object to be created naturally (use a container of objects...not pointers) or if I really need pointers, I'll try to use a smart pointer (have a look at the boost library)

    [edit]..read grib's post as he is quicker at typing than me

  4. #4
    Registered User
    Join Date
    Oct 2003
    Posts
    5
    thanks very much for the info.

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Originally posted by Fordy

    [edit]..read grib's post as he is quicker at typing than me
    Only because I use words like wether rite good I should have learned in collage, but the beer was too cheap.

  6. #6
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    In fact, THIS gives no errors on most compilers:

    Code:
    #include <iostream>
    class C{
    public:
    	void dummy(){ std::cout << "Who's a dummy?" << std::endl;}
    };
    
    int main(){
    	C* cptr = NULL;
    	cptr->dummy();
    }
    The reason, as grib said, is that your function call does not attempt to use any member variables. If it doesn't need to access variables inside the class, it never truly dereferences the pointer -- that is, it never attempts to access memory using the pointer. The function is also not virtual, so it does not need to use a vtable in the object (which would again be dereferencing a pointer).

    Of course, it's very bad to do something like this, and you can't expect it to work on all compilers, but it typically will, because there is no need to dereference the pointer when you don't need to access data.

    Also, a function that was not virtual and that did not access any class data members doesn't need to be part of a class anyhow, so this result happens because it is a special case, and not typical of any real-world object.

    Oh, and as Fordy said, I also highly recommend boost for low-maintenence, container-safe smart pointers.
    Last edited by Cat; 11-10-2003 at 01:33 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Alice....
    By Lurker in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 06-20-2005, 02:51 PM
  2. Debugging question
    By o_0 in forum C Programming
    Replies: 9
    Last Post: 10-10-2004, 05:51 PM
  3. Question about pointers #2
    By maxhavoc in forum C++ Programming
    Replies: 28
    Last Post: 06-21-2004, 12:52 PM
  4. Question...
    By TechWins in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 07-28-2003, 09:47 PM
  5. Question, question!
    By oskilian in forum A Brief History of Cprogramming.com
    Replies: 5
    Last Post: 12-24-2001, 01:47 AM