[Boost-bugs] [Boost C++ Libraries] #8512: set member_hook access violation

Subject: [Boost-bugs] [Boost C++ Libraries] #8512: set member_hook access violation
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2013-04-28 20:00:46


#8512: set member_hook access violation
------------------------------------+---------------------------------------
 Reporter: toby_toby_toby@… | Owner: igaztanaga
     Type: Bugs | Status: new
Milestone: To Be Determined | Component: intrusive
  Version: Boost 1.53.0 | Severity: Showstopper
 Keywords: |
------------------------------------+---------------------------------------
 Visual Studio 2012 express, all patches. 32 bits.

 Iterator dereference returns wrong pointer (offset by 4 bytes from
 normal).

 I think it's because of virtual inheritance, mistake in
 offset_from_pointer_to_member (intrusive/detail/parent_from_member.hpp)

 Output of program below:
>>>
 offsets: 4 and 8
 pointers: 00BEF94C and 00BEF948
 <<<





 #include <iostream>
 #include <string>
 #include <boost/noncopyable.hpp>
 #include <boost/intrusive/set.hpp>

 namespace intrusive = boost::intrusive;

 class object : public boost::noncopyable
 {
 public:
     object()
         {
         }
     virtual ~object()
         {
         }
 };


 class signal : virtual public object
 {
 public:
         signal()
         {
         }
         virtual ~signal()
         {
         }
 };


 class record : public signal
 {
 public:
     record()
         {
         }
     virtual ~record()
         {
         }

 public:
         virtual const std::string& get_buffer() const
         {
                 return m_buffer;
         }

         typedef intrusive::set_member_hook<
                 intrusive::link_mode<intrusive::auto_unlink>
> hook;
         hook m_hook;

         std::string m_buffer;
 };


 template <class T, class M, M (T::*V)>
 struct member_comparator
 {
     bool operator()(const T& t1, const T& t2) const
     {
         return (t1.*V) < (t2.*V);
     }
     bool operator()(const M& m, const T& t) const
     {
         return m < (t.*V);
     }
     bool operator()(const T& t, const M& m) const
     {
         return (t.*V) < m;
     }
 };

 typedef member_comparator<
     record,
     std::string,
     &record::m_buffer
> record_comparator;

 typedef intrusive::set<
     record,
     intrusive::compare<record_comparator>,
     intrusive::member_hook<
         record,
         record::hook,
         &record::m_hook
>,
     intrusive::constant_time_size<false>
> records
     ;


 int main(int argc, char** argv)
 {
         union
         {
                 int32_t as_int;
                 const record::hook record::* ptr_to_member;
         }
         sss;
         sss.ptr_to_member = &record::m_hook;

         std::cout << "offsets: " << sss.as_int << " and " <<
 offsetof(record,m_hook) << std::endl;

         records rr;

         std::string key = "123";
         records::insert_commit_data icd;
         std::pair<records::iterator,bool> ir = rr.insert_check(
                 key,
                 record_comparator(),
                 icd
                 );

         if ( !ir.second )
         {
                 throw std::exception();
         }

         record rec;
         rec.m_buffer = key;
         records::iterator i = rr.insert_commit( rec, icd );

         record* rrr = &(*i);

         std::cout << "pointers: " << ((void*)rrr) << " and " <<
 ((void*)&rec) << std::endl;

         return 0;
 }

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/8512>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:12 UTC