Fix small memory leak that occurred when loading a ROM with auto-resume enabled and now resume save file currently exists. Created fceuScopedPtr class type to help prevent memory leaks on temporary memory allocations in functions with early outs.

This commit is contained in:
harry 2023-01-30 23:10:03 -05:00
parent d4c2a7e2d9
commit be9ad4ccf2
2 changed files with 66 additions and 15 deletions

View File

@ -723,7 +723,7 @@ bool FCEUSS_LoadFP(EMUFILE* is, ENUM_SSLOADPARAMS params)
bool FCEUSS_Load(const char *fname, bool display_message)
{
EMUFILE* st;
fceuScopedPtr <EMUFILE> st; // fceuScopedPtr will auto delete the allocated EMUFILE at function return.
std::string fn;
//mbg movie - this needs to be overhauled
@ -743,14 +743,15 @@ bool FCEUSS_Load(const char *fname, bool display_message)
{
st = FCEUD_UTF8_fstream(fname, "rb");
fn.assign(fname);
} else
}
else
{
fn = FCEU_MakeFName(FCEUMKF_STATE,CurrentState,fname);
st=FCEUD_UTF8_fstream(fn.c_str(),"rb");
lastLoadstateMade.assign(fn);
}
if (st == NULL || (st->get_fp() == NULL))
if (st.get() == NULL || (st.get()->get_fp() == NULL))
{
if (display_message)
{
@ -764,27 +765,27 @@ bool FCEUSS_Load(const char *fname, bool display_message)
//If in bot mode, don't do a backup when loading.
//Otherwise you eat at the hard disk, since so many
//states are being loaded.
if (FCEUSS_LoadFP(st, backupSavestates ? SSLOADPARAM_BACKUP : SSLOADPARAM_NOBACKUP))
if (FCEUSS_LoadFP(st.get(), backupSavestates ? SSLOADPARAM_BACKUP : SSLOADPARAM_NOBACKUP))
{
if (fname)
{
char szFilename[260]={0};
splitpath(fname, 0, 0, szFilename, 0);
if (display_message)
if (display_message)
{
FCEU_DispMessage("State %s loaded.", 0, szFilename);
FCEU_DispMessage("State %s loaded.", 0, szFilename);
//FCEU_DispMessage("State %s loaded. Filename: %s", 0, szFilename, fn.c_str());
}
} else
}
}
else
{
if (display_message)
if (display_message)
{
FCEU_DispMessage("State %d loaded.", 0, CurrentState);
FCEU_DispMessage("State %d loaded.", 0, CurrentState);
//FCEU_DispMessage("State %d loaded. Filename: %s", 0, CurrentState, fn.c_str());
}
}
SaveStateStatus[CurrentState] = 1;
}
delete st;
#ifdef _S9XLUA_H
if (!internalSaveLoad)
@ -807,7 +808,7 @@ bool FCEUSS_Load(const char *fname, bool display_message)
#endif
#ifdef __WIN_DRIVER__
Update_RAM_Search(); // Update_RAM_Watch() is also called.
Update_RAM_Search(); // Update_RAM_Watch() is also called.
#endif
//Update input display if movie is loaded
@ -817,7 +818,8 @@ bool FCEUSS_Load(const char *fname, bool display_message)
cur_input_display = FCEU_GetJoyJoy(); //Input display should show the last buttons pressed (stored in the savestate)
return true;
} else
}
else
{
if(!fname)
SaveStateStatus[CurrentState] = 1;
@ -827,7 +829,6 @@ bool FCEUSS_Load(const char *fname, bool display_message)
FCEU_DispMessage("Error(s) reading state %d!", 0, CurrentState);
//FCEU_DispMessage("Error(s) reading state %d! Filename: %s", 0, CurrentState, fn);
}
delete st;
return 0;
}
}

View File

@ -62,6 +62,8 @@ typedef signed int int32;
#define alloca __builtin_alloca
#endif
//#include <typeinfo>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@ -177,6 +179,54 @@ typedef uint8 (*readfunc)(uint32 A);
#define __FCEU_PRINTF_ATTRIBUTE( fmt, va )
#endif
// Scoped pointer ensures that memory pointed to by this object gets cleaned up
// and deallocated when this object goes out of scope. Helps prevent memory leaks
// on temporary memory allocations in functions with early outs.
template <typename T>
class fceuScopedPtr
{
public:
fceuScopedPtr( T *ptrIn = nullptr )
{
//printf("Scoped Pointer Constructor <%s>: %p\n", typeid(T).name(), ptrIn );
ptr = ptrIn;
}
~fceuScopedPtr(void)
{
//printf("Scoped Pointer Destructor <%s>: %p\n", typeid(T).name(), ptr );
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
T* operator= (T *ptrIn)
{
ptr = ptrIn;
return ptr;
}
T* get(void)
{
return ptr;
}
void Delete(void)
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
private:
T *ptr;
};
#include "utils/endian.h"
#endif