Memory fragmentation?

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
piotrek.zorawski
Posts: 2
Joined: Fri Jan 30, 2009 9:58 pm

Memory fragmentation?

Post by piotrek.zorawski »

Hello! I have a weird problem with loading images with OSLib.
When I allocate memory for image, then load and free it everything works fine. If I repeat it for about 100 times with the same image - everything is still ok. But at the attempt no. 101 OSLib returns error - no such file.
There is not enough ram. I've tested it via PSP_HEAP_SIZE_KB(18*-1024); - it crashes after about 10 attempts.
I believe, that malloc cannot allocate enough space in fragmented memory. I think that this is a stupid question (modifing every pointer in a program, lol ), but is there any way to defragment memory automatically?

Here's a code sample of my image loader (I read image from an one, big, merged file (data.dat), where the information about merged files is in data.h)

Code: Select all

typedef struct {
        char  name[32];
        int len; 
        int offset; 
        } OCB_FILE;

void * imagebuff; //global image buffer

  OCB_FILE * ocb_exists_notify(const char *filename) //gets the information about storaged file (it's lenght, offset and name)
     {
          OCB_FILE *ocb =(OCB_FILE *) malloc(sizeof(OCB_FILE));  
          FILE * ocb_header = fopen (OCB_FHEADER, "r" );
          char line [ 128 ]; 
          char ocb_name[128];
          int ocb_len=0;
          int ocb_offset=0;
          while ( fgets ( line, sizeof line, ocb_header ) != NULL ) 
            {
             sscanf (line,"- %s %d %d", ocb_name, &ocb_len, &ocb_offset);
             if (strcmp(ocb_name, filename) == 0)
                {
                              ocb->len=ocb_len;
                              strcpy(ocb->name, ocb_name);
                              ocb->offset=ocb_offset;
                              fclose(ocb_header);
                              return ocb;
               }
            }
    char * error=(char *)malloc(255);
    sprintf(error, "no file: %s", filename);
    oslFatalError(error);
    return 0;
     }

char * ocb_read(OCB_FILE * ocb) { //reads file 
         char * buffer=(char *) malloc(ocb->len);
         FILE *input = fopen (OCB_FDATA, "rb" );
          if (input==NULL)  oslFatalError("error opening data file!");
         fseek (input , ocb->offset, SEEK_SET );
         fread (buffer,1, ocb->len,input);
         fclose ( input );         
         return buffer;
     }

OSL_IMAGE * ocb_loadimage(const char * filename,  int location, int pixelFormat) { //loads image
          OCB_FILE *ocb=malloc(sizeof(OCB_FILE));
          ocb=ocb_exists_notify(filename);
          free(imagebuff);
          imagebuff=malloc(ocb->len); 
          imagebuff=ocb_read(ocb);          
          oslSetTempFileData(imagebuff, ocb->len, &VF_MEMORY);
          
	char *ext, extension[10];
	int i;
	ext = strrchr(filename, '.');
	if (!ext)
		return NULL;
	i = 0;
	while&#40;ext&#91;i&#93; && i < sizeof&#40;extension&#41; - 2&#41;
	&#123;
		extension&#91;i&#93; = tolower&#40;ext&#91;i&#93;&#41;;
		i++;
	&#125;
	extension&#91;i&#93; = 0;
	if &#40;!strcmp&#40;extension, ".png"&#41;&#41;
		return oslLoadImageFilePNG&#40;oslGetTempFileName&#40;&#41;, location, pixelFormat&#41;;
	else if &#40;!strcmp&#40;extension, ".jpg"&#41;&#41;
	return oslLoadImageFileJPG&#40;oslGetTempFileName&#40;&#41;, location, pixelFormat&#41;;
	else if &#40;!strcmp&#40;extension, ".gif"&#41;&#41;
	return oslLoadImageFileGIF&#40;oslGetTempFileName&#40;&#41;, location, pixelFormat&#41;;
return NULL;          
          &#125;
Best regards
Piotrek &#379;órawski
Last edited by piotrek.zorawski on Sun Feb 01, 2009 2:54 am, edited 1 time in total.
User avatar
Wally
Posts: 663
Joined: Mon Sep 26, 2005 11:25 am

Post by Wally »

Instead of 18*-1024, try -1024 by itself.

Report back :)
piotrek.zorawski
Posts: 2
Joined: Fri Jan 30, 2009 9:58 pm

Post by piotrek.zorawski »

I've used 18*-1024 to see if it's ram related - malloc crashes after a few times.
Simply, -1024 fails, but 18*-1024 does it faster.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

I think your code is leaking memory. Look at one part of the code:

Code: Select all

          OCB_FILE *ocb=malloc&#40;sizeof&#40;OCB_FILE&#41;&#41;;
          ocb=ocb_exists_notify&#40;filename&#41;;
You store allocated memory into ocb, then change the pointer, orphaning the memory block. You probably have other similar issues... your use of allocated memory for temporary structures is downright bizarre! NOBODY allocates memory for a filename! For all the mallocing you are doing, I don't see anywhere near as many frees to clean it all up. I'd recommend tossing this code and starting over. Try making some flow charts and blocking out the code ahead of time.
Post Reply