Omnimaga

Calculator Community => TI Calculators => Calculator C => Topic started by: Matrefeytontias on September 25, 2012, 01:02:14 pm

Title: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on September 25, 2012, 01:02:14 pm
Hi guys !

I'm programming in C with Ndless, and I'm confused about a thing : I used several variables, I malloc'd all my pointers, I freed them before exiting, I also SDL_FreeSurface'd all the concerned pointers and ... I still have huge memory leaks (leading to a crash) :banghead:

I post the code here, and if you can see something, please tell me :( :
Spoiler For Spoiler:
Code: [Select]
#include <os.h>
#include <SDL/SDL.h>
#include <fdlibm.h>

int main(void) {
SDL_Surface *screen;
SDL_Surface **ship;
SDL_Surface *shots;
SDL_Rect shipPos;
SDL_Rect *shotPos;

static unsigned short **shipSprites;
static unsigned short *shotSprites;

int shipAnim = 0;

int *activeShot;
int currentShot = 0;
int shootDelay = 0;
int i, j;

// Malloc for SDL_Surface *screen
screen = malloc(sizeof(SDL_Surface));
if(screen == NULL) exit(0);

// Malloc for SDL_Surface *ship[3]
ship = malloc(3*sizeof(SDL_Surface));
if(ship == NULL)
{
free(screen);
exit(0);
}
for(i = 0; i < 3; i++)
{
ship[i] = malloc(sizeof(SDL_Surface));
if(ship[i] == NULL)
{
free(screen);
for(j = 0; j < i; j++) free(ship[j]);
free(ship);
exit(0);
}
}

// Malloc for SDL_Surface *shots
shots = malloc(sizeof(SDL_Surface));
if(shots == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
exit(0);
}

// Malloc for SDL_Rect shotPos[128]
shotPos = malloc(128 * sizeof(SDL_Rect));
if(shotPos == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
exit(0);
}

// Malloc for int activeShot[128]
activeShot = malloc(128 * sizeof(int));
if(activeShot == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
free(shotPos);
exit(0);
}
for(i = 0; i < 128; i++) activeShot[i] = 0;

// Malloc for static unsigned short shipSprites[3][1408]
shipSprites = malloc(3 * sizeof(*shipSprites));

if(shipSprites == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
free(activeShot);
free(shotPos);
exit(0);
}

for(i = 0; i < 3; i++)
{
shipSprites[i] = malloc(1408 * sizeof(unsigned short));
if(shipSprites[i] == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
for(j = 0; j < i; j++) free(shipSprites[j]);
free(shipSprites);
free(activeShot);
free(shotPos);
exit(0);
}
}

#include "shipSpritesC.util"

// Malloc for static unsigned short shotSprites[49]
shotSprites = malloc(49 * sizeof(unsigned short));

if(shotSprites == NULL)
{
free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
for(i = 0; i < 3; i++) free(shipSprites[i]);
free(shipSprites);
free(activeShot);
free(shotPos);
exit(0);
}


#include "shotSpritesC.util"

SDL_Init(SDL_INIT_VIDEO);

screen = SDL_SetVideoMode(320, 240, is_cx?16:8, SDL_SWSURFACE);

shots = nSDL_LoadImage(shotSprites);

for(i = 0; i < 3; i++) ship[i] = nSDL_LoadImage(shipSprites[i]);

for(i = 0; i < 127; i++) activeShot[i] = 0;

while(!isKeyPressed(KEY_NSPIRE_ESC))
{
if(isKeyPressed(KEY_NSPIRE_DOWN) && shipPos.y < 204) shipPos.y++;
if(isKeyPressed(KEY_NSPIRE_LEFT) && shipPos.x > 0) shipPos.x--;
if(isKeyPressed(KEY_NSPIRE_RIGHT) && shipPos.x < 281) shipPos.x++;
if(isKeyPressed(KEY_NSPIRE_UP) && shipPos.y > 0) shipPos.y--;

if(isKeyPressed(KEY_NSPIRE_LEFT) && !isKeyPressed(KEY_NSPIRE_RIGHT)) shipAnim = 1;
else if (isKeyPressed(KEY_NSPIRE_RIGHT) && !isKeyPressed(KEY_NSPIRE_LEFT)) shipAnim = 2;
else shipAnim = 0;

if(isKeyPressed(KEY_NSPIRE_CTRL) && !shootDelay)
{
activeShot[currentShot] = 1;
shotPos[currentShot].x = shipPos.x + (ship[shipAnim]->w - shots->w)/2;
shotPos[currentShot].y = shipPos.y;
currentShot = (currentShot + 1) % 128;
shootDelay = 32;
}

for(i = 0 ; i < 127 ; i++)
{
if(activeShot[i])
{
shotPos[i].y -= 3;
SDL_BlitSurface(shots, NULL, screen, &shotPos[i]);
if(shotPos[i].y < 4) activeShot[i] = 0;
}
}

SDL_BlitSurface(ship[shipAnim], NULL, screen, &shipPos);
SDL_Flip(screen);
SDL_FillRect(screen, NULL, (Uint32)0xFFFFFFFF);

shootDelay = (shootDelay > 0 ? shootDelay - 1 : 0);
}

SDL_FreeSurface(shots);
SDL_FreeSurface(screen);
for(i = 0; i < 3; i++)
{
SDL_FreeSurface(ship[i]);
}

free(screen);
for(j = 0; j < 3; j++) free(ship[j]);
free(ship);
free(shots);
free(shotSprites);
for(i = 0; i < 3; i++) free(shipSprites[i]);
free(shipSprites);
free(activeShot);
free(shotPos);

SDL_Quit();
return 0;
}
The *.util files is the files where I fill shipSprites and shotSprites with sprites' datas. I'm not doing anything more than repetitively write "shipSprites[blah][blah] = ..."
Title: Re: [Ndless] Memory leaks happen anyway
Post by: calc84maniac on September 25, 2012, 01:10:10 pm
Shouldn't you be doing ship = malloc(3*sizeof(SDL_Surface *)); ? As far as I can tell, you need to allocate space for 3 pointers, not three surfaces. I don't think this is causing the error though, since it just means you're allocating more space than needed.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on September 25, 2012, 01:25:39 pm
Oh yeah, I'll correct that and I'll see.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: hoffa on September 25, 2012, 01:30:32 pm
A few things: you're using dynamic allocations enormously, you should use static allocations a lot more. They're generally safer, easier to handle and makes your code more readable and maintainable. Only use malloc if the dynamic solution is actually better (i.e., when you know the size of your data structure, go for static allocation). In your case why not just have int activeShot[128] instead of activeShot = malloc(128 * sizeof(int)), for instance? It saves you from redundant memory management and avoids all the hassles of it.

Also there's no need to allocate memory for the screen surface, SDL takes care of it. SDL has a pretty good event system, you should use it for your key handling.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on September 25, 2012, 02:27:28 pm
Okay, I'll take care of that. None of you see what should cause this leak ?
Title: Re: [Ndless] Memory leaks happen anyway
Post by: hoffa on September 25, 2012, 02:32:12 pm
It's quite a pain to read through the code because of the high amount of mallocs and whatnot. Clean up your code as much as possible (it may be possible that every malloc/free can be removed and replaced with static allocations) and try again, the crash could be caused by different things; I doubt it has anything to do with a memory leak.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on September 25, 2012, 02:40:44 pm
It crashes if I try to display the available memory in any way, even by the Status menu.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Lionel Debroux on September 25, 2012, 02:53:19 pm
Quote
It crashes if I try to display the available memory in any way, even by the Status menu.
You have probably overrun some buffer and corrupted memory.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: aeTIos on September 26, 2012, 08:56:00 am
code in spoiler D:
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on September 29, 2012, 10:03:35 am
In fact it's ok, I just cleaned all the malloc and now it works correctly ???

I'll keep this thread open in case of another problem :)
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on October 02, 2012, 09:15:53 am
/me ups

I re-use this topic to post another similar problem :

I have a huge 16388 elements-array, and whatever the way I use to initialize it, it still doesn't work when I try to access it.

Here's my code (crashes when reach the only line involving texture[][]) :
Code: [Select]
#include <os.h>
#include <common.h>
#include <fdlibm.h>
#include "utils.h"
#include "texture.h"

#define TEXTURE_WIDTH 128
#define TEXTURE_HEIGHT 128

int main(void)
{
char *screen;
double (*angle_lut)[240];
double (*depth_lut)[240];
double relativeX, relativeY, tempRelative, angle, textureX, textureY;

int w = 240, h = 240, x, y, color, screenX, screenY;

angle_lut = malloc(240 * sizeof(*angle_lut));
if(!angle_lut) exit(0);

depth_lut = malloc(240 * sizeof(*depth_lut));
if(!depth_lut)
{
free(angle_lut);
exit(0);
}

screen = malloc(SCREEN_BYTES_SIZE * sizeof(char));
if(!screen)
{
free(angle_lut);
free(depth_lut);
exit(0);
}

for(y = 0; y < h; y++)

{
for(x = 0; x < w; x++)
{
relativeX = x - w / 2;
relativeY = h / 2 - y;
tempRelative = relativeX * relativeX + relativeY * relativeY;

if(!tempRelative) depth_lut[x][y] = 0.0;
else depth_lut[x][y] = 8388608 / tempRelative;

if(!relativeY)
{
if(relativeX < 0) angle = -64;
else angle = 64;
}
else
{
angle = atan(relativeX / relativeY) / (2*M_PI) * 128;
if(relativeY > 0) angle += 128;
}

angle_lut[x][y] = angle * 8;
}
}

while(!isKeyPressed(KEY_NSPIRE_ESC))
{
clearBuf(screen);
for(screenY = 0; screenY < h; screenY++)
{
for(screenX = 0; screenX < w; screenX++)
{
x = screenX - w/2;
y = h/2 - screenY;
// X is the angle, Y is the depth
textureX = angle_lut[x][y];
textureY = depth_lut[x][y];

while(x < 0)
{
x += TEXTURE_WIDTH;
}
while(y < 0)
{
y += TEXTURE_HEIGHT;
}
while(x > TEXTURE_WIDTH)
{
x -= TEXTURE_WIDTH;
}
while(y > TEXTURE_HEIGHT)
{
y -= TEXTURE_HEIGHT;
}

color = texture[(int)textureY % 128][(int)textureX];      ←   crashes when reach this line
color %= 256;
setPixelBuf(screen, screenX+40, screenY, (int)(abs(color-1)/16));
}
}
refresh(screen);
}

free(screen);
free(angle_lut);
free(depth_lut);
return 0;
}

And here is texture.h :
Spoiler For Spoiler:
Code: [Select]
unsigned short texture[128][128] = {
{ 0x2a01, 0x80, 0x80, 0x0, 0xad54, 0x944f, 0xa4b0, 0xa4b0, 0x9c90, 0xa4b0, 0xa4b0, 0xa4b0, 0xa4b0, 0xa46f, 0x9c6f, 0x942f, 0x9c6f, 0x9c4f, 0x9c6f, 0xa490, 0xacd0, 0xacd0, 0xa4b0, 0xacb0, 0x9c4f, 0xa46f, 0x942e, 0x8bed, 0x8c0e, 0x942f, 0x8bee, 0xa470, 0xa470, 0x9c90, 0x9c4f, 0x942e, 0xa470, 0xa490, 0xa4d0, 0xa4d1, 0xa4d1, 0xa4f1, 0xa4d1, 0xa4d1, 0xa4d1, 0xad11, 0xad32, 0xad12, 0xa4b0, 0xa4d0, 0xa4d0, 0xa4d1, 0xa4b0, 0xa4b0, 0x9cb0, 0xa4f1, 0xacf1, 0xa4f1, 0xa4f1, 0xad11, 0xacf1, 0xa4b1, 0xa4d1, 0xb532, 0xb572, 0xa4d1, 0xa4b1, 0xa4b0, 0x9cb0, 0x9c90, 0xa4b0, 0xa4b0, 0x9c6f, 0x9c90, 0x9c90, 0xa4b0, 0xa4f1, 0xa4d0, 0xa4b0, 0x9cb0, 0xa4d0, 0xacf1, 0xa4f1, 0xa4f0, 0xa4d0, 0xad12, 0xad12, 0xa4d0, 0xa4d1, 0xa4d1, 0xa4b0, 0xad32, 0xb553, 0xad11, 0xa4b0, 0xacf1, 0xb532, 0xb552, 0xb552, 0xbd73, 0xb532, 0xa4d1, 0x9c8f, 0xa4d0, 0xa4b1, 0x9c6f, 0x9c8f, 0x946f, 0x946f, 0x9caf, 0x944f, 0x9470, 0x944f, 0x9c70, 0x946f, 0x948f, 0xa4b0, 0x9c8f, 0x9c6f, 0x944f, 0x946f, 0xacf1, 0xa4d0, 0xa4b0, 0x9c6f, 0x9cb0, 0xa4f1, 0x9c6f },
{ 0x944f, 0x944f, 0x944f, 0x83ee, 0x7b8c, 0x5a67, 0x6267, 0x5a67, 0x6aa8, 0x6288, 0x6287, 0x6287, 0x6aa7, 0x6267, 0x5a46, 0x5a26, 0x5a46, 0x5a46, 0x6287, 0x6267, 0x5a46, 0x6287, 0x6267, 0x6267, 0x5206, 0x5a46, 0x5206, 0x41a4, 0x4a05, 0x5226, 0x49c5, 0x5a26, 0x5a46, 0x5a46, 0x5a26, 0x5a46, 0x6287, 0x5a67, 0x6287, 0x6287, 0x6287, 0x62a8, 0x6ac8, 0x62a8, 0x6288, 0x6288, 0x6ac8, 0x62a8, 0x62a7, 0x62a8, 0x5a87, 0x6287, 0x62a7, 0x62a7, 0x62a8, 0x6ae8, 0x62a7, 0x6287, 0x6287, 0x6287, 0x6287, 0x6288, 0x6ac8, 0x62c7, 0x5aa7, 0x6287, 0x6288, 0x5a67, 0x5a67, 0x5a67, 0x62a7, 0x5a67, 0x5a67, 0x6287, 0x5a67, 0x5a67, 0x62a8, 0x6287, 0x5a87, 0x5a47, 0x5a67, 0x62a7, 0x62c8, 0x6ae8, 0x62a8, 0x6ae8, 0x6ac8, 0x6287, 0x5a67, 0x62a7, 0x62a8, 0x6ac8, 0x6ac8, 0x6ae8, 0x62c7, 0x62a7, 0x62c8, 0x6ae9, 0x6b09, 0x6ae8, 0x5aa7, 0x5266, 0x5246, 0x5266, 0x5aa7, 0x5266, 0x5226, 0x5226, 0x5a46, 0x5246, 0x4a06, 0x4a06, 0x49e5, 0x5226, 0x4a26, 0x5226, 0x5246, 0x5246, 0x5a66, 0x5246, 0x5226, 0x5a67, 0x5a47, 0x5246, 0x49e5, 0x5226, 0x6287, 0x5226 },

etcetera ...
};

What can it be ?
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Lionel Debroux on October 02, 2012, 01:20:55 pm
Missing relocations ? Try to force relocation of texture[][] with nl_relocdata.
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Matrefeytontias on October 02, 2012, 01:25:06 pm
I don't know this func, how does it work ? (while we're on it)
Title: Re: [Ndless] Memory leaks happen anyway
Post by: Lionel Debroux on October 02, 2012, 01:28:04 pm
Have a look at the headers / documentation ;)