Null pointer problem.

Started by Anteater, Fri 22/05/2009 23:11:57

Previous topic - Next topic

Anteater

In my script, every enemy has an active time battle variable (if you've played any oldschool Squaresoft games, you'll know what I'm talking about). The variable is between 0 and 100, with 100 being full. When the gauge is full, the enemy attacks. The problem comes when assigning an ATB value to each enemy. Since properties are read-only, I'm using a 1D array for the ATB gauge, like so:
Code: ags
int atb[];
int j = 0;
function repetedly_execute()
{
  
  while(j<Game.CharacterCount)
  {
    atb[j] = atb[j] + 1;
    if(j > Game.CharacterCount)
    {
      j = 0;
    }
  }
}

Then, this function causes will contain the code for the actual attack process:
function enemyBattle(this Character*)
{
 
  if(atb[this.ID]>99)
  {
    PlaySound(3);
  }
}
This function is an extender used by enemy characters. Obviously it isn't close to being finished yet. My problem is that the if line causes a null pointer error.
What am I doing wrong?
At the end of the script, I'm exporting the atb[] variable, if that makes any difference.

It's at times like this that I miss C++  ;D

GarageGothic

#1
As for the null pointer error, could it be due to the dynamic array atb[] never being initialized? Somewhere, e.g. in game_start(), there should be a line saying "atb = new int[Game.CharacterCount];" before you can start using it.

Also, I see a couple of problems here:

Code: ags
while(j<Game.CharacterCount) {
  atb[j] = atb[j] + 1;
  if(j > Game.CharacterCount) {
    j = 0;
    }
  }


First of all, you're setting the function to run as long as j is LESS than Game.CharacterCount, yet within that loop you check if it's MORE than Game.CharacterCount. This will never register as true so j is never reset to 0. Another thing is that j itself is never increased within the while loop (you increase atb[j] but not j itself), so I would expect the game to get stuck in an endless loop at that point.

Edit: Oh, and you shouldn't set j to 0 within the while loop, this will just keep it running forever (or until the game crashes after 150,000 iterations). In fact, unless you're using the j variable elsewhere in the script you might as well declare it inside the repeatedly_execute so it is destroyed once the function finishes and there's no need to reset it.

DoorKnobHandle

Quote from: Anteater on Fri 22/05/2009 23:11:57
It's at times like this that I miss C++  ;D

For the record, C/C++ doesn't exactly take kindly to null pointers either.

monkey0506

#3
GG correctly identified the fact that (based on what's shown) you've never allocated the array. Just to show you how it should look:

Code: ags
int atb[];

function game_start()
{
  atb = new int[Game.CharacterCount];
  /* optional - initialize the variables */
  int i = 0;
  while (i < Game.CharacterCount)
  {
    atb[i] = 0;
    i++;
  }
  // the items are all initialized to 0 automatically but you can assign them a different default value
  // possibly randomizing the starting value such as:
  // atb[i] = Random(100);
}

function repeatedly_execute()
{
  int j = 0;
  while(j < Game.CharacterCount)
  {
    atb[j]++;
    if (atb[j] > 100) atb[j] = 100;
    j++;
  }
}

function enemyBattle(this Character*)
{
  if(atb[this.ID] == 100)
  {
    PlaySound(3);
    // run battle script
    atb[this.ID] = 0;
  }
}


Basically, seeing as you're referencing C++ you can think of an AGS int[] as a C++ int*. You don't have to dereference it and the deallocation is automatic and you can only allocate an array...However when you first declare the array it's not yet been allocated to anything. You must let AGS know how big the required array size is so it can allocate the memory. This isn't PHP here... :P

Anteater

Quote from: dkh on Sat 23/05/2009 02:07:22
Quote from: Anteater on Fri 22/05/2009 23:11:57
It's at times like this that I miss C++  ;D

For the record, C/C++ doesn't exactly take kindly to null pointers either.
I was actually referring to C++'s ability to add variables to classes easily, thus eliminating the need for global variables.

Thank you for the help; I forgot to initialize the array with the new keyword.
Yeah, I know the loop doesn't work quite right; I hacked it together in a hurry.

DoorKnobHandle

Again, you can assign variables to classes in AGS the same way you can in C++.

Glad you sorted the problem out!

SMF spam blocked by CleanTalk