tags:

views:

79

answers:

3

Hi In my program I am creating an object of a class in a loop and storing it in a vector. Then I print the address of the object and the member variable. After that I erase them . I see that every time I see the same address assigned to my object and the member variable which is a pointer. Can any one explain this behavior.

#include <iostream>
#include <vector>

using namespace std;

typedef struct csock {
unsigned int _refCount;
mutable pthread_mutex_t _pdata_mutex;
pthread_attr_t attr;
bool _bSocketClosed;            /// used for testing while closing the socket
int _iSockFD;                   /// Holds the native socket descriptor
void* _pfnArgs; 
void* _logger;                  /// For debug logging
bool _isServiceRunning; 
pthread_t _thread_id;           /// Thread id for the listener service
int _pipes[2];                  /// For stop signal communication
pthread_mutex_t* _countMutex;
unsigned long  _idleTimeOut;                //Idle Time Out
FILE* fp;
} __attribute__((packed)) csock_t;




class csocket
{
protected:
void* _pImpl;

public :

csocket(){
csock_t* ps = new csock_t;
this->_pImpl = reinterpret_cast<void*> (ps);
std::cout<<"\n ps is "<<ps <<" _pImpl is "<<_pImpl <<endl;
}
void* getImpl()
{
    return _pImpl;
}
};


int main ()
{

vector<csocket> v;

 for (int i=0; i< 5; ++i) {
    v.push_back(csocket());
    cout<<"\n after pushback "<<v[v.size()-1].getImpl();
    cout<<"\n after pushback object is"<<&(v[v.size()-1]);
    delete (csock_t*) v[0].getImpl();
    v.erase(v.begin()+0);
}
cout <<"\n size of vector is "<<v.size();
return 0;
}

I am adding the output in my system

ps is 0x8368008 _pImpl is 0x8368008
after pushback 0x8368008
after pushback object is0x8368078

ps is 0x8368008 _pImpl is 0x8368008
after pushback 0x8368008
after pushback object is0x8368078

ps is 0x8368008 _pImpl is 0x8368008
after pushback 0x8368008
after pushback object is0x8368078

ps is 0x8368008 _pImpl is 0x8368008
after pushback 0x8368008
after pushback object is0x8368078

ps is 0x8368008 _pImpl is 0x8368008
after pushback 0x8368008
after pushback object is0x8368078
+3  A: 

After you delete the object the memory it previously occpied is marked as free and its ownership is passed to the heap, so the heap is allowed to reuse the space it occupied for future allocations. So it just happens that the heap reuses exactly the same memory block.

sharptooth
Ok so you all feel this is normal then thanks a lot for the quick answers.
punith
+1  A: 

Once an object is deleted, the memory it occupied is handed back to the runtime (or to the OS, in some cases) for reuse. If you go and allocate memory for another object of exactly the same size, or sometimes even a little bit smaller, that chunk of memory is probably the best fit -- so it's quite reasonable to use that chunk of memory instead of carving another chunk out from somewhere else and raising the chance of memory fragmentation issues later on.

cHao
Ok, I knew the heap would re use it but I did not expect it to happen so soon, I expected a small gap before the same address is reused.
punith
Sometimes there's a gap, sometimes there isn't. Depends on the allocator used, what's been created and deleted up to that point, and a few other things. But once you delete something, in C and C++, its memory is *immediately* handed back to the runtime and is immediately eligible for reuse. Whether it's actually reused immediately is up to the allocator.
cHao
A: 

I think what you are looking for is storage based on a weak pointer. Your vector stores weak pointers to the connection objects. Your main application gets the shared pointers. The destructor for your connection object frees the resource. Periodically you can pack the vector by erasing all weak pointers with a use_count of zero.

class Connect;

typedef boost::shared_ptr<Connect> ConnectPtr;
typedef boost::weak_ptr<Connect> ConnectWeakPtr;
typedef std::vector<ConnectWeakPtr> ConnectVector;

ConnectVector vector;

ConnectPtr ptr( new Connect ( ... ));

vector.push_back(ptr);

void pack() {
    ConnectVector tmp;
    BOOST_FOREACH(ConnectWeakPtr const & p, mMap){
        if (p.use_count() > 0){
            tmp.insert(p);
        }
        mMap.swap(tmp);
    }
}
bradgonesurfing