c++ - emptying an std::queue through a function that returns the front() and pops() -
i'm writing template class supposed provide queue protected against concurrent access, able write classes can treat list of items variable number of concurrent worker threads.
the template class has method:
bool getfront(t &value) { critsectex::scope scope(listlock); bool ret = false; if( !itemlist.empty() ){ value = itemlist.front(); itemlist.pop(); ret = true; } return ret; }
which locks queue, , if it's not empty fetches 1st element, pops , returns true, each worker can do
while( getfront(entry) ){ // entry ntreated += 1; } // exit worker
the question is: returning here through value
reference? when test code, double free error because type t
i'm using contains pointer (let's call b) that's deleted in dtor (when b not marked being pointer global structure). dtor has been called during pop() in getfront(), seems logical. took care type t's ctors allocate copy of b when creating new t existing instance , not subclass provide '=' operator, i'm not sure how i'd end 2 instances of t each contain same value of b , "we own b" member.
i don't sort of thing enough, i'm overlooking here, what? suggestions how troubleshoot this?
additional observation: appears it's last element popped queue shows behaviour.
to make less vague, here's use typename t:
struct folder_info { // plenty of members snipped #ifdef __cplusplus public: folder_info() { memset( this, 0, sizeof(struct folder_info) ); } folder_info(const struct folder_info *src) { init(src); } folder_info(const struct folder_info &src) { init(&src); } private: void init(const struct folder_info *src) { memcpy( this, src, sizeof(struct folder_info) ); // don't duplicate filetypeslist! filetypeslist = null; filetypeslistlen = filetypeslistsize = 0; } #endif }; typedef struct fileentry { public: std::string filename; struct stat fileinfo; folderinfo *folderinfo; bool freefolderinfo; fileentry(); fileentry( const char *name, const struct stat *finfo, folderinfo *dinfo, const bool owninfo=false ); fileentry( const char *name, const struct stat *finfo, folderinfo &dinfo ); fileentry(const fileentry &ref); ~fileentry(); } fileentry; fileentry::fileentry() { folderinfo = null; freefolderinfo = false; } fileentry::fileentry( const char *name, const struct stat *finfo, folderinfo *dinfo, const bool owninfo ) { filename = name; fileinfo = *finfo; folderinfo = (owninfo)? new folderinfo(dinfo) : dinfo; freefolderinfo = owninfo; } fileentry::fileentry( const char *name, const struct stat *finfo, folderinfo &dinfo ) { // creating fileentry folderinfo reference makes copy // of folderinfo structure fileentry( name, finfo, new folderinfo(dinfo), true ); } fileentry::fileentry(const fileentry &ref) { filename = ref.filename; fileinfo = ref.fileinfo; if( ref.freefolderinfo ){ folderinfo = new folderinfo(ref.folderinfo); } else{ folderinfo = ref.folderinfo; } freefolderinfo = ref.freefolderinfo; } fileentry::~fileentry() { if( freefolderinfo && folderinfo ){ delete folderinfo; folderinfo = null; } }
in case right, problem lack of user-defined assignment operator fileentry
.
your copy constructor takes care of fact each fileentry
has new folderinfo
if copied fileentry
has freefolderinfo == true
, whereas assignment operator not.
if assign 1 fileentry
1 , if both have freefolderinfo == true
, you'll delete same pointer twice, last of 2 goes out of scope / deleted.
what rule of three?
if need explicitly declare either destructor, copy constructor or copy assignment operator yourself, need explicitly declare 3 of them.
Comments
Post a Comment