   access violation in Release() sbuffer
  I'm just breaking into DirectSound - I have created a SynthSound object which initializes DirectSound and creates a secondary sound buffer.All the functions seem to return DS_OK.  However, when SynthSound::Cleanup() is called, I get an error box that says, "Unhandled exception at 0x00416b53 in synth.exe: 0xC0000005: Access violation reading location 0xfeeefef6."  The debugger then points me to the line where I Release() my secondary buffer.Here's the code://within SynthSound.h#include <dsound.h>class SynthSound{public:SynthSound(void);bool Setup(HWND hWnd);bool SetupSounds();void Cleanup();bool all_is_ok;protected:LPDIRECTSOUND dsound;LPDIRECTSOUNDBUFFER test_sound;};//within SynthSound.cpp#include <dsound.h>#include "SynthSound.h"SynthSound::SynthSound(void){dsound=0;test_sound=0;all_is_ok=false;}bool SynthSound::Setup(HWND hWnd){if(!DirectSoundCreate(0,&dsound,0)==DS_OK){all_is_ok=false;return false;}//set cooperative levelif(dsound->SetCooperativeLevel(hWnd,DSSCL_NORMAL)!=DS_OK){all_is_ok=false;return false;}if(!SetupSounds()){all_is_ok=false;return false;}all_is_ok=true;return true;}bool SynthSound::SetupSounds(){DSBUFFERDESC dsbd;WAVEFORMATEX wvfmt;memset(&wvfmt,0,sizeof(WAVEFORMATEX));wvfmt.wFormatTag=WAVE_FORMAT_PCM;wvfmt.nChannels=1;wvfmt.nSamplesPerSec=11025;wvfmt.nBlockAlign=1;wvfmt.nAvgBytesPerSec=wvfmt.nSamplesPerSec*wvfmt.nBlockAlign;wvfmt.wBitsPerSample=8;wvfmt.cbSize=0;memset(&dsbd,0,sizeof(DSBUFFERDESC));dsbd.dwSize=sizeof(DSBUFFERDESC);dsbd.dwFlags=DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN |   DSBCAPS_CTRLVOLUME |  DSBCAPS_STATIC | DSBCAPS_LOCSOFTWARE;dsbd.dwBufferBytes=22050;dsbd.lpwfxFormat=&wvfmt;test_sound=0;if(DS_OK!=dsound->CreateSoundBuffer(&dsbd,&test_sound,NULL)){all_is_ok=false;test_sound=0;return false;}else{all_is_ok=true;}return true;}void SynthSound::Cleanup(){if(dsound){ dsound->Release(); }if(test_sound){ test_sound->Release(); }return;}This is truly boggling, because when the error box appears, the debugger tells me that test_sound definitely has a value (so it's not as if I'm Release()-ing a NULL pointer) and all_is_ok is true, which has to mean that there were no problems with the creation of the sound buffer.Can anyone explain what is going on?Thanks!-synth_cat   
  Well, if I had to guess, I'd say that your program is calling Release() too many times. Most likely cause of the problem is that your SynthSound class doesn't AddRef() when doing a copy construction or assignment (as it defines neither operation and thus violates the Rule of Three).   ;  Have you any trace information that suggests you might already have released those buffers? You're not using the SAFE_RELEASE() macro which NULL's the ptr after its released. Helps a lot when tracking down these cases - I've accidentally attempted to release buffers multiple times. Once the RefCount is at zero the pointer is invalid, even if it has a seemingly legitimate value.Try using SAFE_RELEASE() and if the error turns to accessing a NULL pointer you've probably found your problem. Throwing in some OutputDebugString( L"Cleanup() called, releasing now!!\n" ); type lines in can ensure you are (or aren't) calling the code multiple times.hthJack   ;  You seem to be releasing the secondary buffer after releasing the DirectSound object. While I'm not too sure about how DirectSound works, and while the idea behind reference counting should make this okay, I'm pretty sure calling dsound->Release() would also release or invalidate your secondary buffer, if the application hadn't done so yet. Try releasing the secondary buffer first, and then the DirectSound object.Also, I'd recommend zeroing out the pointers (test_sound = 0; dsound = 0), in case CleanUp is being called twice by accident.Hope this helps.[EDIT] bah - 6 minutes :([Edited by - sirob on August 11, 2006 10:14:21 AM];Quote:Original post by sirobYou seem to be releasing the secondary buffer after releasing the DirectSound object.I'm pretty sure that's it. I recall having the same problem a while back.   ;  Thanks for all the help, guys!Quote:You seem to be releasing the secondary buffer after releasing the DirectSound object. While I'm not too sure about how DirectSound works, and while the idea behind reference counting should make this okay, I'm pretty sure calling dsound->Release() would also release or invalidate your secondary buffer, if the application hadn't done so yet. Try releasing the secondary buffer first, and then the DirectSound object.Wow, I can't believe I missed that!  I have made this error before, but this is the first time it has actually crashed an app, so I didn't think of it.  I switched the calls, and the error disappeared.  Thanks!Quote:Most likely cause of the problem is that your SynthSound class doesn't AddRef() when doing a copy construction or assignment (as it defines neither operation and thus violates the Rule of Three).I thought that AddRef() was automatically called upon the creation of objects - is it really something you have to keep track of yourself?  What is the Rule of Three?  (Please forgive me ignorance.)Quote:Try using SAFE_RELEASE() and if the error turns to accessing a NULL pointer you've probably found your problem. Throwing in some OutputDebugString( L"Cleanup() called, releasing now!!\n" ); type lines in can ensure you are (or aren't) calling the code multiple times.SAFE_RELEASE() sounds interesting, but I have never seen it before.  Is it defined in d3d9.h?  Is it something people usually use in pro-game-development?Is this what a call would look like?SAFE_RELEASE(test_sound);SAFE_RELEASE(dsound);Thanks again for all your trouble!-synth_cat;  The SAFE_RELEASE() macro does similar to what sirob suggested with zeroing out your pointers.In the samples it tends to be defined in dxstdafx.h:#define SAFE_RELEASE(p) {if(p){(p)->Release();(p)=NULL;}}#define SAFE_DELETE(p) {if(p){delete (p);(p)=NULL;}}#define SAFE_DELETE_ARRAY(p) {if(p){delete[] (p);(p)=NULL;}}The latter two are similar, but used in place of regular deallocations.By ensuring that you zero out "dead" pointers you make it very easy to verify that it is indeed finished with. Its a good practice to follow [smile]hthJack   ;  Thanks for explaining that!   ;Quote:Quote:Most likely cause of the problem is that your SynthSound class doesn't AddRef() when doing a copy construction or assignment (as it defines neither operation and thus violates the Rule of Three).... What is the Rule of Three?  (Please forgive me ignorance.)As it pertains to C++, the Rule of Three basically states that if you have a class that requires a destructor, a copy constructor or an assignment operator, then you probably need all three.What SiCrane was alluding to was that with your current implementation, if you were to copy an instance of SynthSound, either via a copy constructor or assingment, both instances would point to the same buffers. Then if they both try to release them you run into trouble.Consider either implementing a private copy constructor and assignment operator (so you class cannot be copied) or look into "IDirectSound8::DuplicateSoundBuffer" to copy sound buffers.Also, I don't think you actually have to release sound buffers, just the main DirectSound object. I don't have a reference, but I remember when I was implemening my DirectSound wrapper I found somewhere in the SDK a note that releasing the main DirectSound object will also release all sound buffers created with it. That's why attempting to release a buffer after releasing the main object causes problems.Hope that helps, good luck.   ;  Thanks for explaining that!  It seems like I won't need to worry about this rule, though, as I will definitely only ever create one SynthSound manager object.