2010-08-12 5 views
0

Dans mon programme, je crée un objet d'une classe dans une boucle et le stocke dans un vecteur. Ensuite, j'imprime l'adresse de l'objet et la variable membre. Après cela, je les efface. Je vois que chaque fois que je vois la même adresse assignée à mon objet et la variable membre qui est un pointeur. Quelqu'un peut-il expliquer ce comportement.Obtenir la même mémoire encore et encore

#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; 
} 

J'ajoute la sortie dans mon système

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

Il n'y a aucune raison pour laquelle vous ne pourriez pas recevoir la même adresse pour un nouvel objet du même type que celui qui vient d'être supprimé. Quel comportement vous attendiez-vous à voir? –

+0

Pour être franc, mon problème est beaucoup plus grand. Je pense qu'un pointeur partagé résoudra mon problème. Je maintiens un vecteur d'objet de connexion tcp. Je les supprime du vecteur une fois qu'ils ne sont plus nécessaires. mais le vecteur est sous un mutex, donc au moment où je le supprime et le retire du vecteur, un autre objet avec la même adresse est créé et ajouté au vecteur. Mon critère de suppression était basé sur l'adresse de l'objet, donc maintenant dans le vecteur j'ai deux objets avec la même adresse qui est morte et une autre qui a été nouvellement créée. Cela me causait des accidents intempestifs. – punith

+0

vous l'avez fait mal. vous devez modifier vos critères de suppression/ou/ne supprimez aucun objet lors de l'exécution du code de suppression (?) .... ou utilisez un pointeur intelligent. –

Répondre

0

Je pense que ce que vous cherchez est le stockage basé sur un pointeur faible. Votre vecteur stocke des pointeurs faibles sur les objets de connexion. Votre application principale obtient les pointeurs partagés. Le destructeur de votre objet de connexion libère la ressource . Périodiquement, vous pouvez compresser le vecteur en effaçant tous les pointeurs faibles avec un use_count de zéro.

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

Une fois que vous delete l'objet la mémoire qu'il précédemment occpied est marqué comme libre et sa propriété est passée au tas, de sorte que le tas est autorisé réutiliser l'espace qu'il occupait pour les allocations futures. Il arrive donc que le tas réutilise exactement le même bloc de mémoire.

+0

Ok, donc vous vous sentez tous que c'est normal alors merci beaucoup pour les réponses rapides. – punith

1

Une fois qu'un objet est supprimé, la mémoire qu'il occupe est restituée au runtime (ou au système d'exploitation, dans certains cas) pour être réutilisée. Si vous allez allouer de la mémoire pour un autre objet de la même taille, ou parfois même un peu plus petit, ce morceau de mémoire est probablement le meilleur ajustement - il est donc raisonnable d'utiliser ce morceau de mémoire au lieu de découper un autre morceau d'ailleurs et augmentant la chance de problèmes de fragmentation de la mémoire plus tard.

+0

Ok, je savais que le tas le réutiliserait mais je ne m'attendais pas à ce que ça arrive si vite, je m'attendais à un petit écart avant que la même adresse ne soit réutilisée. – punith

+0

Parfois, il y a un écart, parfois il n'y en a pas. Cela dépend de l'allocateur utilisé, de ce qui a été créé et supprimé jusqu'à ce point, et de quelques autres choses. Mais une fois que vous avez supprimé quelque chose, en C et C++, sa mémoire est * immédiatement * remise à l'exécution et est immédiatement admissible à la réutilisation. Qu'il soit réellement réutilisé immédiatement dépend de l'allocateur. – cHao

Questions connexes