diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m index 26da64d7ed..66a8c9efc6 100644 --- a/src/audio/coreaudio/SDL_coreaudio.m +++ b/src/audio/coreaudio/SDL_coreaudio.m @@ -806,7 +806,34 @@ static int assign_device_to_audioqueue(_THIS) result = AudioObjectGetPropertyData(this->hidden->deviceID, &prop, 0, NULL, &devuidsize, &devuid); CHECK_RESULT("AudioObjectGetPropertyData (kAudioDevicePropertyDeviceUID)"); result = AudioQueueSetProperty(this->hidden->audioQueue, kAudioQueueProperty_CurrentDevice, &devuid, devuidsize); - CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); + + /* + If AudioObjectGetPropertyData succeeds and AudioQueueSetProperty fails, + calling CHECK_RESULT("AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"); + will cause a memory leak since it returns + */ + + // !!! FIXME: do we need to CFRelease(devuid) + /* Yes + CFStringRef is passed to AudioObjectGetPropertyData as an argument of type + UnsafeMutableRawPointer. As stated in the Apple Developer Documentation, + "The UnsafeMutableRawPointer type provides no automated memory management, + no type safety, and no alignment guarantees. You are responsible for + handling the life cycle of any memory you work with through + unsafe pointers, to avoid leaks or undefined behavior" + */ + + //This is the quickest fix + if (result != noErr) { + const char* msg = "AudioQueueSetProperty (kAudioQueueProperty_CurrentDevice)"; + SDL_Log("COREAUDIO: Got error %d from '%s'!\n", (int)result, msg); + CFRelease(devuid); + SDL_SetError("CoreAudio error (%s): %d", msg, (int)result); + return 0; + } + + //Release once you've finished using CFStringRef + CFRelease(devuid); return 1; }