_BLOCK_TYPE_IS_VALID assertion with maps

Hi,

In the following code, I have a _BLOCK_TYPE_IS_VALID assertion when the CDeviceManager destructor is called.
The 'IAudioCallBackDevice *caller' argument is an object created and destroyed outside this code.
Could someone give me some suggestion? I cannot find where is the mistake!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  class IAudioCallBackDevice;  
  class CDeviceManager;  

  template<class T>
  class Singleton : private boost::noncopyable
  {

    public:
      static T& instance()
      {
          boost::call_once(init, flag);
          return *t;
      }

      static void init() // never throws
      {
          t.reset(new T());
      }

    protected:
      ~Singleton() {}
       Singleton() {}

    private:
       static boost::scoped_ptr<T> t;
       static boost::once_flag flag;

  };

  template<class T> boost::scoped_ptr<T>  Singleton<T>::t(0);
  template<class T> boost::once_flag      Singleton<T>::flag = BOOST_ONCE_INIT;

  
  //----------------------------------------------------------------------------

  class CDevicesManager : public Singleton<CDevicesManager>
  { 
    friend class Singleton<CDevicesManager>;

    typedef std::map<LONG, CDeviceManager*> TManagersMap;

    public:

      EAudioLibRetVal   InitDevice(LONG                 device_id,
                                   RtAudio::Api         audio_api,
                                   IAudioCallBackDevice *caller);

      ~CDevicesManager();

    private:
      TManagersMap  Managers_;  // A manager for each phisical device

  };

  //----------------------------------------------------------------------------


  class CDeviceManager
  { 
    
    struct TAudioDevParams
    {
      RtAudio::StreamParameters  OutParams;
      RtAudio::StreamParameters  InParams;
      RtAudioFormat              Format; 
      unsigned int               SampleRate;
      unsigned int               BufferFrames;
      RtAudio::StreamOptions     Options;
    };

    struct TCallbackUserData
    {
      CDeviceManager* ptrThis;
      RtAudio::Api    CurrentApi;
    };


    typedef RtAudio*                pAudioDev;
    typedef IAudioCallBackDevice*   pListener;

    typedef std::map<INT, pListener>                  TListeners;
    typedef std::map<RtAudio::Api, TListeners>        TListenersMap;
    typedef std::map<RtAudio::Api, pAudioDev>         TAudioDevsMap;
    typedef std::map<RtAudio::Api, TAudioDevParams>   TAudioDevParamsMap;
    typedef std::map<RtAudio::Api, TCallbackUserData> TCallbackUserDataMap;


    public:

      void              NotifyDeviceHandlerDestroy(IAudioCallBackDevice *caller);

      EAudioLibRetVal   InitDevice(RtAudio::Api         audio_api,
                                   IAudioCallBackDevice *caller);


      CDeviceManager(CDevicesManager* Manager, LONG DeviceID) : 
                     Manager_(Manager), 
                     DeviceID_(DeviceID) {};

      ~CDeviceManager();

    private:

      CDevicesManager*      Manager_;
      LONG                  DeviceID_;       // The Device ID which the manager refers to
      TAudioDevsMap         Devs_;           // From RtAudio::Api::LINUX_ALSA to RtAudio::Api::WINDOWS_DS
      TListenersMap         ListenersMap_;   // From RtAudio::Api::LINUX_ALSA to RtAudio::Api::WINDOWS_DS

  };

  //----------------------------------------------------------------------------

  class IAudioCallBackDevice
  {
  public:
    IAudioCallBackDevice() 
    {
      srand((unsigned)time(0));
      id_ = rand();
    };

    ~IAudioCallBackDevice() 
    { // Notify to the Manager when a Device handler is destroyed
      if (dev_manager_) 
        dev_manager_->NotifyDeviceHandlerDestroy(this); 
    };

    inline void SetDeviceManager(CDeviceManager* dev_manager, RtAudio::Api audio_api)
    { // Sets the Device handler Manager
      dev_manager_ = dev_manager;
      audio_api_ = audio_api;
    };

    inline RtAudio::Api GetApi() { return audio_api_; }

    virtual INT AudioCallBack(void *AudioBuffer,
                              UINT nFrames,
                              double streamTime,
                              RtAudioStreamStatus status) = 0;
    
    inline CDeviceManager* getDeviceManager() { return dev_manager_; };

    inline INT GetID() { return id_; };

    inline bool operator!=(const IAudioCallBackDevice& obj) const {
      return (this->id_ != obj.id_);
    }

    inline bool operator==(const IAudioCallBackDevice& obj) const {
      return (this->id_ == obj.id_);
    }

  private:
    CDeviceManager* dev_manager_;
    RtAudio::Api    audio_api_;
    INT             id_;
  };


The implementation...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//----------------------------------------------------------------------------

EAudioLibRetVal CDevicesManager::InitDevice(LONG                  device_id,
                                            RtAudio::Api          audio_api,
                                            IAudioCallBackDevice  *caller)
{

  // First of all check if already exist a DeviceManager for device_id
  // and if it doesn't, create it
  if ( Managers_.find(device_id) == Managers_.end() )
    Managers_[device_id] = new CDeviceManager(this, device_id);

  // Set the caller's DeviceManager
  (caller)->SetDeviceManager( Managers_[device_id], audio_api );

  return Managers_[device_id]->InitDevice( audio_api, caller );

};

//----------------------------------------------------------------------------

CDevicesManager::~CDevicesManager()
{
  for( TManagersMap::iterator it = Managers_.begin(); it != Managers_.end(); it++ )
    delete it->second;
}



//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------



CDeviceManager::~CDeviceManager()
{
  //for(TAudioDevsMap::iterator it = Devs_.begin(); it != Devs_.end(); it++ )
  TAudioDevsMap::iterator dev = Devs_.begin();
  while(dev != Devs_.end())
  {
    if (dev->second->isStreamRunning()) dev->second->stopStream();
    delete dev->second;
    Devs_.erase( dev );
    dev = Devs_.begin();
  }
  
  TListenersMap::iterator it = ListenersMap_.begin();

  while(it != ListenersMap_.end())
  {
    // Remove all listeners
    TListeners listeners = it->second;
    while (listeners.size() > 0)
      listeners.erase(listeners.begin());

    //Remove the listeners map
    ListenersMap_.erase( it );
    it = ListenersMap_.begin();
  }
}

//----------------------------------------------------------------------------

EAudioLibRetVal CDeviceManager::InitDevice(RtAudio::Api         audio_api,
                                           IAudioCallBackDevice *caller)
{
  try {

    // Searching if the RtAudio class exists for the given Api
    // If not, crete it
    if ( Devs_.find(audio_api) == Devs_.end() )
      Devs_[audio_api] = new RtAudio(audio_api);

    DeviceInfo_ = Devs_[audio_api]->getDeviceInfo(DeviceID_);

    TListeners lst = ListenersMap_[audio_api];
    
    // Add the listeners
    if ( lst.find( caller->GetID() ) == lst.end() )
      lst[caller->GetID()] =  caller;

    // Return a pointer to the device
    return RV_NO_ERROR;
  } 
  catch (RtError& e) { return static_cast<EAudioLibRetVal>(e.getType()); }

}

//----------------------------------------------------------------------------

void CDeviceManager::NotifyDeviceHandlerDestroy(IAudioCallBackDevice* caller)
{
  // When a device handler is destroyed, I remove it from the listeners list
  ListenersMap_[ caller->GetApi() ].erase( caller->GetID() );
};
Sounds like that you trying to delete an element twice or more, please check your code by some profiler, for example by Intel Parallel Studio
Found it.
It was an error on a memcpy! Damn! :)

Daniele.
Topic archived. No new replies allowed.