ios - Possible bug in libc++ for mac os ,string destructor is not called when string obj goes out of scope -


in libc++ have found basic_string destructor not gets called , once string goes out of scope memory freed calling delete operator rather calling destructor , calling delete operator destructor, why so?

can 1 explain this? see sample program

void * operator new ( size_t len ) throw ( std::bad_alloc ) {     void * mem = malloc( len );     if ( (mem == 0) && (len != 0) )          throw std::bad_alloc();     return mem; }  void operator delete ( void * ptr ) throw() {     if ( ptr != 0 )          free( ptr ); }  int main(int argc, const char * argv[])  {     std::string  mystr("testing very big string string class");     std::string mystr2(mystr1.begin(),mystr.end()); } 

put break point on new , delete , check call stack. new operator gets called basic_string class while delete gets called end of main, while ideally basic_string destructor should have called first , delete operator should called via deallocate call of allocator, valid 2nd string creation.

i'm seeing same thing in debugger are; don't know sure, suspect stuff getting inlined. destructor basic_string small; single test (for small string optimization), , call allocator's deallocate function (through allocate_traits). std::allocators allocate function quite small, wrapper around operator delete.

you test writing own allocator. (later: see below)

more stuff generated while investigating question; read on if you're interested.

[note: there's bug in code - in second line wrote: mystr1.begin(),mystr.end()) - mystr1 declared?]

assuming that's typo, tried different code:

#include <string> #include <new> #include <iostream>  int news = 0; int dels = 0;  void * operator new ( size_t len ) throw ( std::bad_alloc ) {     void * mem = malloc( len );     if ( (mem == 0) && (len != 0) )          throw std::bad_alloc();     ++news;     return mem; }  void operator delete ( void * ptr ) throw() {     ++dels;     if ( ptr != 0 )          free( ptr ); }  int main(int argc, const char * argv[])  {     {     std::string mystr("testing very big string string class");     std::string mystr2(mystr.begin(),mystr.end());     std::cout << "news = " << news << "; dels = " << dels << std::endl;     }     std::cout << "news = " << news << "; dels = " << dels << std::endl;  } 

if run code, prints (at least me):

news = 2; dels = 0 news = 2; dels = 2 

which should.

if toss code compiler explorer, see both calls basic_string::~basic_string(), expect. (well, see three of them, 1 of them in exception handling block, ends call _unwind_resume).

later - code:

#include <string> #include <new> #include <iostream>  int news = 0; int dels = 0;  template <class t> class myallocator { public:     typedef t value_type;      myallocator() noexcept {}      template <class u>     myallocator(myallocator<u>) noexcept {}      t* allocate(std::size_t n)     {         ++news;         return static_cast<t*>(::operator new(n*sizeof(t)));     }      void deallocate(t* p, std::size_t)     {         ++dels;         return ::operator delete(static_cast<void*>(p));     }      friend bool operator==(myallocator, myallocator) {return true;}     friend bool operator!=(myallocator, myallocator) {return false;} };   int main(int argc, const char * argv[])  {     {     typedef std::basic_string<char, std::char_traits<char>, myallocator<char>> s;     s mystr("testing very big string string class");     s mystr2(mystr.begin(),mystr.end());     std::cout << "allocator news = " << news << "; allocator dels = " << dels << std::endl;     } std::cout << "allocator news = " << news << "; allocator dels = " << dels << std::endl; } 

prints:

 allocator news = 2; allocator dels = 0  allocator news = 2; allocator dels = 2 

which confirms allocator getting called.


Comments

Popular posts from this blog

python - How to insert QWidgets in the middle of a Layout? -

python - serve multiple gunicorn django instances under nginx ubuntu -

module - Prestashop displayPaymentReturn hook url -