GP32 Malloc


pea

developer
Joined
Oct 3, 2004
Messages
1,089
Age
45
Location
New Zealand
Website
www.projectitis.com
Hi all,

I am re-writing the GIF routines because the malloc/free flow is much less than optimal (i.e. its pretty damn random, malloc in one function, free in a completely different one).

Just wanted to confirm. If I have a struct like this:
Code:
typedef struct tGPD_gif{
	int width;	
	int height;
	short *imag;
}tGPD_gif;
And then I allocate memory for the struct like this:
Code:
tGPD_gif *gif;
gif = malloc( some_size );
gif->imag = malloc( some_other_size);

Then freeing 'gif' without first freeing 'gif->imag' is going to result in a leak, right?

Cheers,
Pea
 
Correct. Also, if you free "gif" first, then try to delete "gif->image", you may be dereferencing an invalid pointer, so could even crash the machine and require a reset.

Then freeing 'gif' without first freeing 'gif->imag' is going to result in a leak, right?
 
Last edited by a moderator:
Hi!
You have to free the image data first an then free the gif struct. For allocating the gif struct use malloc(sizeof(tGPD_gif)) and for allocating the gif, something like malloc(heigth*width*sizeof(short)).
Correct me if i'm wrong.

When i use malloc, my programs crash on the gp. It gets ok when using gp_mem_func.malloc(...)
 
Thanks for the last tip kmkzk and don. I was going to ask that question next because I see the original GIF lib uses something like gm_malloc... mine has been working ok on geepee32 so far (I don't have a GP32 yet)
 
Just another Q regarding malloc and free..

If I call 'free' on a struct that HASN'T yet had memory allocated using malloc, will my app crash? In other words...

Can I do this (extrremely simplified example):
Code:
typedef struct tMyStruct{
  int number;
}

void main( void ){
  tMyStruct *t1;
  tMyStruct *t2;

  t1 = createMyStruct( -3 ); // will return NULL
  t2 = createMyStruct( 5 ); // will return valid struct

  free( t1 ); // #### THIS #### <- t1 doesnt actually have memory allocated
  free( t2 );
}

tMyStruct* createMyStruct( num ){
  tMyStruct *mine;
  
  if (num<0){
    return NULL;
  }
  mine = (tMyStruct*)malloc( sizeof(tMyStruct) );
  mine->number = num;
  
  return mine;
}

Or do I have to do this?
Code:
typedef struct tMyStruct{
  int number;
}

void main( void ){
  tMyStruct *t1;
  tMyStruct *t2;

  t1 = createMyStruct( -3 ); // will return NULL
  t2 = createMyStruct( 5 ); // will return valid struct

  if (t1!=NULL){ free( t1 ); }
  if (t2!=NULL){ free( t2 ); }
}

tMyStruct* createMyStruct( num ){
  tMyStruct *mine;
  
  mine=NULL;

  if (num>=0){
    mine = (tMyStruct*)malloc( sizeof(tMyStruct) );
    mine->number = num;
  }
  
  return mine;
}

I don't want to have to check for NULLs if I don't specifically need to.

Also, are pointers NULL by default, or could they be pointing to arbitrary memory locations and need to be manually assigned NULL?
 
pea posted on Dec 18 2004 at 03:59 AM said:
Just another Q regarding malloc and free..

If I call 'free' on a struct that HASN'T yet had memory allocated using malloc, will my app crash? In other words...

Can I do this (extrremely simplified example):
Code:
typedef struct tMyStruct{
  int number;
}

void main( void ){
  tMyStruct *t1;
  tMyStruct *t2;

  t1 = createMyStruct( -3 ); // will return NULL
  t2 = createMyStruct( 5 ); // will return valid struct

  free( t1 ); // #### THIS #### <- t1 doesnt actually have memory allocated
  free( t2 );
}

tMyStruct* createMyStruct( num ){
  tMyStruct *mine;
  
  if (num<0){
    return NULL;
  }
  mine = (tMyStruct*)malloc( sizeof(tMyStruct) );
  mine->number = num;
  
  return mine;
}

Or do I have to do this?
Code:
typedef struct tMyStruct{
  int number;
}

void main( void ){
  tMyStruct *t1;
  tMyStruct *t2;

  t1 = createMyStruct( -3 ); // will return NULL
  t2 = createMyStruct( 5 ); // will return valid struct

  if (t1!=NULL){ free( t1 ); }
  if (t2!=NULL){ free( t2 ); }
}

tMyStruct* createMyStruct( num ){
  tMyStruct *mine;
  
  mine=NULL;

  if (num>=0){
    mine = (tMyStruct*)malloc( sizeof(tMyStruct) );
    mine->number = num;
  }
  
  return mine;
}

I don't want to have to check for NULLs if I don't specifically need to.

Also, are pointers NULL by default, or could they be pointing to arbitrary memory locations and need to be manually assigned NULL?


Hi Pea,

Under my Linux OS, I've just checked the manual page for free (by typing "man 3 free"), and here is what it tells :

"free(void* ptr) frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc(), or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed".

So I think you should check for NULL, and just after a free (ptr), do a ptr=NULL .

Could you please post here, or on your web site, your complete modified source for GIF loading, because I'm a bit lazy to adapt it for Mirko SDK...

Thanks...
 
Last edited by a moderator:
Hi Palmic,

Thanks for your reply. Just after posting I spent a while debugging a problem, and it turned out to be exactly the issue here - I was trying to free a struct that had already been freed, and it kept crashing. I don't have any sort of debugger, so it is very slow - I comment out all the code, and then uncomment sections at a time until geepee32 crashes, and then I narrow down the prob!!

There is a bug in the code whereby the resulting colours are completely screwed up unless the palette has all 256 colours! For example, a GIF with only 12 colours will have random colours. I am trying to work on this, but does anyone have any idea as to why?

I will post my GIF code on my website. Please note that is loads the GIF into a custom struct, which is of the form:
Code:
typedef struct tGPD_canvas{
	int width;
	int height;
	unsigned short *data;
}tGPD_canvas;
There are two functions you can use to load the GIFs (I have used the 16bpp version, not rov's modified 8bpp version). One loads a GIF from SMC, and the other simply decodes a GIF already in memory.

You can also specify whether you want the code to rotate the GIF data by 90degrees. This could be the default, but I wanted to account for GIFs that are already pre-rotated.
Code:
// ### canvasCreateFromGif
// Assigns memory and loads a GIF from the smc. The GIF is converted
// to a 16bpp canvas structure.
extern tGPD_canvas* gpd_canvasCreateFromGif(
	char *filename,      // in:  path to GIF file on smc
	char rotate90,      // in:  If non zero will rotate data 90 deg (not req. for pre-rotated images)
	int *outError      	// out:  Error code (see defines above)
);

// ### canvasCreateFromGifBuf
// Assigns memory and decodes a GIF file stored in memory (buffer). The
// GIF is converted to a 16bpp canvas structure.
extern tGPD_canvas* gpd_canvasCreateFromGifBuf(
	unsigned char *gifdata,  // in:  pointer to the GIF data in memory
	char rotate90,      // in:  If non zero will rotate data 90 deg (not req. for pre-rotated images)
	int *outError      	// out:  Error code (see defines above)
);

The functions are used like this:
Code:
tGPD_canvas *canvas;
int res;

canvas = gpd_canvasCreateFromGif( "dev0:\\gpmm\\mygif.gif", 1, &res );
if (res){
  // error occured
}else{
  ...
  gpd_canvasFree( canvas );
}

EDIT:
Code can be found here:
http://www.pea.co.nz/gp32/gpd_downloads.php
 
Back
Top