Is IMG_Load_RW freeing buffer created with new[]?

Hi, in some code I load images from a zip file via Physfs.

This Method loads the image from the zip file into a RWops

Code:

SDL_RWops* GameEngine::LoadFromZip(std::string target)
{
// Archive is mounted in GameEngine::Init()

// Check if target file is in archive
if(PHYSFS_exists(target.c_str()) == 0)
{
// handle error
}

// Open target file
PHYSFS_file *file = PHYSFS_openRead(target.c_str());
if(file == nullptr)
{
// handle error
}

// Read target into memory
PHYSFS_sint64 filesize = PHYSFS_fileLength(file);
char *buffer = new char[filesize];
if(PHYSFS_read(file, buffer, sizeof(char), filesize) != filesize)
{
// handle error
}
PHYSFS_close(file);

// Create RWops
SDL_RWops *rwops = SDL_RWFromMem(buffer, filesize);
if(rwops == nullptr)
{
// handle error
}

// delete[] buffer; // CRASH
return rwops;
}

and the returned RWops is used in some functions to load create s Surface, Texture ect…
e.g.

Code:

SDL_Surface* GameEngine::LoadSurface(std::string filename)
{
// Load image from memory
SDL_RWops *rwops = LoadFromZip(filename);
SDL_Surface *surface = IMG_Load_RW(rwops, 1);
if(surface == nullptr)
{
// handle error
}

return surface;
}

I’m not sure what happens with the buffer allocated in the LoadFromZip Function.
Is it freed by

SDL_Surface *surface = IMG_Load_RW(rwops, 1);

?

The code works, but when I put a delete[] buffer just before the return of the LoadFromZip function,
the programm crashes.

What’s the right way to do this, if I don’t want to write the code of the LoadFromZip funtion in every function I use for loading
surfaces, textures, mix_chunks ect. from the zip file.

P.S.

I didn’t post the error checkings in the code … :wink:

The rwops is only a handle for accessing the buffer data in a common way.
It does not keep an extra copy of the buffer, so if you delete the buffer
before the rwops, then you’re effectively pulling the rug out from under
the rwops. You will have to manually delete the buffer when you are all
done with the rwops.

There’s a PhysFS extension, physfsrwops, that you should use to avoid that
extra buffer. That might help your use case here.

Jonny DOn Sunday, March 22, 2015, sanitowi <michael.straube1 at gmx.de> wrote:

Hi, in some code I load images from a zip file via Physfs.

This Method loads the image from the zip file into a RWops

Code:

SDL_RWops* GameEngine::LoadFromZip(std::string target)
{
// Archive is mounted in GameEngine::Init()

// Check if target file is in archive
if(PHYSFS_exists(target.c_str()) == 0)
{
// handle error
}

// Open target file
PHYSFS_file *file = PHYSFS_openRead(target.c_str());
if(file == nullptr)
{
// handle error
}

// Read target into memory
PHYSFS_sint64 filesize = PHYSFS_fileLength(file);
char *buffer = new char[filesize];
if(PHYSFS_read(file, buffer, sizeof(char), filesize) != filesize)
{
// handle error
}
PHYSFS_close(file);

// Create RWops
SDL_RWops *rwops = SDL_RWFromMem(buffer, filesize);
if(rwops == nullptr)
{
// handle error
}

// delete[] buffer; // CRASH
return rwops;
}

and the returned RWops is used in some functions to load create s Surface,
Texture ect…
e.g.

Code:

SDL_Surface* GameEngine::LoadSurface(std::string filename)
{
// Load image from memory
SDL_RWops *rwops = LoadFromZip(filename);
SDL_Surface *surface = IMG_Load_RW(rwops, 1);
if(surface == nullptr)
{
// handle error
}

return surface;
}

I’m not sure what happens with the buffer allocated in the LoadFromZip
Function.
Is it freed by

SDL_Surface *surface = IMG_Load_RW(rwops, 1);

?

The code works, but when I put a delete[] buffer just before the return of
the LoadFromZip function,
the programm crashes.

What’s the right way to do this, if I don’t want to write the code of the
LoadFromZip funtion in every function I use for loading
surfaces, textures, mix_chunks ect. from the zip file.

P.S.

I didn’t post the error checkings in the code … :wink:

Thanks for your hint.
Are there some docs available for the physfsrwops extension?
I have not found any yet…

For now I use a std::vector as buffer in the LoadFromZip function, return a copy of it and create the rwops
in the calling function…

Ok, I was able to get it working with physfsrwops,
but there are two little problems.

I opend another thread for that.
https://forums.libsdl.org/viewtopic.php?p=47383#47383