Suppose I have a following constructor in C++ class:
MyClass::MyClass()
{
char* buffer = malloc(100);
if (0 != someD3DXCallThatCanFail(..., buffer, ...))
{
free(buffer);
throw MyException(L"some message");
}
char* buffer2 = malloc(200);
if (0 != anotherD3DCallThatCanFail(..., buffer2, ...))
{
free(buffer);
free(buffer2);
throw MyException(L"another message");
}
.. more code here where buffer and buffer2 are still used
free(buffer);
free(buffer2);
}
EDIT: I do hate malloc/free and new/delete, but unfortunately I need to use buffers for loading textures which are then passed over to ID3D10ShaderResourceView, ID3D10Buffer, vertex buffer and the like. All those require pointers to a buffer.
What I am trying to do it to use exceptions instead of returning error codes. Also I wish to create buffers where they are needed and free them right after they are no longer needed.
However, what looks ugly is that in case of errors, no matter if I return error codes or throw exceptions, I still should remember to clean up any buffer that was created up to that point. If I have 10 buffers and 10 possible points of error, I will have to call free() 100 times (in each error case remember to free each buffer).
Now suppose I or worse, my colleague wants to change some logic and, say, adds another buffer somewhere in the middle. Now, he'd have to look thru all the errors that can happen in the rest of the method and add free() for that buffer at every such place. If he's in a hurry, he can easily overlook a few such places, and you got a memory leak.
This also bloats the code immensely.
finally keyword would solve that problem in Java or C#. No matter where in the code the exception happened, I'd still clean up all those buffers in "finally" (btw you wouldn't need that with garbage collection). In C++ from what I understand, I may have to create a member variable for any such buffer, and in the destructor make sure the buffers are cleaned up. Looks also quite ugly to me, since a member variable with name "pBuffer", even a private one, is just garbage, since it's only used in the one method (in this case, constructor) and will always be NULL the rest of the time.
Must be a common problem, however I didn't manage to find an answer using search. Thanks!