ObjC/c code error with lists

ededed
Unregistered
 
Post: #1
I cant get this App working i have put <HELP> near possible problems.
Its a simple game I was making but I got stuck with the code to remove bullets from an array, if anyone can help me please do!

http://www.geocities.com/ed72678954/index.html

This is a precursor to rigid body asteroids so fixing it woul be very helpful.
Thanks in ADVANCE?

This is how i feel: :envy: + Wacko + Wow + :sorry: + Blink + Huh + :?:
Quote this message in a reply
ededed
Unregistered
 
Post: #2
Please Help me.
Quote this message in a reply
w_reade
Unregistered
 
Post: #3
(1) You're malloc()ing every time a bullet is fired or hits something, and you never free() anything. This is a Bad Thing, because your memory gets filled up with unreferenced garbage.

(2) You never check for malloc() returning NULL. This is also a Bad Thing, and probably what causes you to crash in the end, when you try to set something belonging to a NULL pointer (which malloc()returned because there wasn't any memory left, because it was full of garbage).

(3) You shouldn't need two arrays anyway.

I might do this in one of two ways, each of which has advantages and disadvantages. Neither requires both bullets[] and tempBullets[].

Possibility 1:

Have a fixed size for your array of bullets, and add an "alive" boolean to the BulletDef structure. Make the array large enough to hold all the bullets that could possibly be on screen at one time, and fill it at game start with bullets whose alive = false. When you loop through the bullets, look at all of them but only bother to process those which are alive; when you fire a bullet, just find a bullet which is not alive, give it the appropriate x, y, xv, yv and set alive = true; when a bullet hits something, simply set alive = false.

Advantages: you can have a bullets[MAX_BULLETS] array in MyCoolOpenGLView, and never need worry about malloc()ing at all, and it'll probably be pretty fast.

Disadvantages: you'll need to work out what to do if you want more bullets than you have space for. You might want to remove the oldest (in which case you'd need to also remember how old each bullet is, although you might like to do this anyway at some stage - just have a timeSpawned variable in your BulletDef), or you might want to not let the user fire until there's a free slot. You should probably handle this case even if you don't believe it could ever happen.

Possibility 2:

Put your bullets in a linked list. You'll need to add a "struct BulletDef *next" to your BulletDef. I really can't be bothered to explain linked lists right now - here's a code snippet from MAFFia; you should be able to work out what's going on.

[SOURCECODE]
Code:
typedef struct ShotEffect
{
    Boolean        readyToDie;
    short        type;
    Point        position;
    short        animationFrame;
    struct ShotEffect    *next;
    
} ShotEffect;

void AddShotEffect (Point where, short type)
{
    ShotEffect        *newShot, *theShot;
    
    if (!(g->pref.shotFX))
        return;
    
    newShot = (ShotEffect *)NewPtr(sizeof(ShotEffect));
    if (!newShot)
        CleanUp(TRUE);
    
    newShot->readyToDie = FALSE;
    newShot->type = type;
    newShot->position = where;
    newShot->animationFrame = 0;
    newShot->next = NULL;
    
    theShot = g->baseShotEffect;
    
    if (!theShot)
        g->baseShotEffect = newShot;
    else
    {
        while (theShot->next)
            theShot = theShot->next;
        
        theShot->next = newShot;
    }
}

void RemoveShotEffect (ShotEffect *theShotEffect)
{
    ShotEffect        *thisShotEffect;
    
    if (theShotEffect != g->baseShotEffect)
    {
        thisShotEffect = g->baseShotEffect;
        
        while (thisShotEffect->next != theShotEffect)
                thisShotEffect = thisShotEffect->next;
        
        thisShotEffect->next = theShotEffect->next;
    }
    else
    {
        g->baseShotEffect = theShotEffect->next;
    }
    
    DisposePtr((Ptr)theShotEffect);
}

void RemoveAllShotEffects (void)
{
    while (g->baseShotEffect)
        RemoveShotEffect(g->baseShotEffect);

    g->baseShotEffect = NULL;
}

void ProcessShotEffects (void)
{
    ShotEffect        *theShotEffect;
    
    theShotEffect = g->baseShotEffect;
    
    while (theShotEffect)
    {
        theShotEffect->animationFrame++;
        
        if (theShotEffect->animationFrame > 19)
            theShotEffect->readyToDie = true;

        theShotEffect = theShotEffect->next;
    }
}
[/SOURCECODE]

Advantages: once you've written your first linked list, you'll feel really clever, and you'll find uses for them everywhere. They have no maximum sixe, so you can have as many bullets as you need without worrying about it (until the computer runs out of memory... but you're freeing the memory you don't need, so this shouldn't happen Wink).

Disadvantages: It'll be slower than the array, since you're allocating and deallocating memory all the time, and may need to jump all over memory as you access the members of the list sequentially. But hey, you're allocating all the time anyway.

Let me know if I can help more, and I'll try... I'll certainly answer specific questions if I can, but I don't feel up to excessively vague/general questions about linked lists.

[edit - source code indenting]
Quote this message in a reply
Apprentice
Posts: 19
Joined: 2002.12
Post: #4
w_reade beat me to the punch, and I agree 100% with what he had to say. Besides the HELP area you had flagged I noticed at least two other locations where you were malloc()'ing memory for your bullet list with no free()'s in sight.

I was going to suggest something similiar to his #1 suggestion.

belboz@cinci.rr.com
Quote this message in a reply
ededed
Unregistered
 
Post: #5
Thank you very much, that is loads of help because I didnt know I had to free things. I was going to store the bullets in a variable length array and the asteroids as a linked list.

What you have said is very helpful. RigidBasteroids coming soon.
Quote this message in a reply
w_reade
Unregistered
 
Post: #6
My pleasure Wink.

Incidentally, there's one thing about the linked list code above that I should mention: I also have a RemoveDeadStuff() function which I call at the end of each frame, which goes through (among other things) the ShotEffect list, and RemoveShotEffect()s any whose readyToDie == true.

There's no particular reason to do that in this case, since nothing else in my program stores pointers to ShotEffects, but if they did then I'd want to look at everything which might have a pointer to a ShotEffect before RemoveDeadStuff()ing, and set the pointer to NULL if the referenced ShotEffect was readyToDie. Otherwise I could end up with nasty dangling pointers and intermittent hard-to-find bugs.

As I said, if you don't keep pointers to bullets anywhere outside their list, then you needn't worry about this, but IMO it's a good habit to fall into... any you should certainly be aware of the problems of dangling pointers. They present all sorts of possibilities for confusion and woe: free()ing the same memory twice will just make you crash, but writing to a dangling pointer could do pretty much anything, and it probably won't always be the same thing each time. Be warned.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  opengl and code::blocks link error supagu 3 4,319 May 28, 2008 03:59 AM
Last Post: GAMERUP
  newbie question about constants in C/objC jspoon 7 3,766 Mar 26, 2005 09:57 PM
Last Post: jspoon
  Vectors vs linked lists KidTsunami 5 3,182 Jun 29, 2003 04:27 AM
Last Post: lpetrich