Recent

Author Topic: [SOLVED] GPF when using GVector pushback()  (Read 2389 times)

mrguzgog

  • Jr. Member
  • **
  • Posts: 71
[SOLVED] GPF when using GVector pushback()
« on: July 30, 2016, 05:29:44 pm »
I have this in the interface of a unit:
Code: [Select]
    uses GVector;
   
    type Location = record
        x, y:   integer;
        v:      integer;
    end;

I'm calling this function:
Code: [Select]
    function meetsCriteria(tempItem: Location; mainList: TVector<Location>): boolean;
    var
        item: Location;
    begin

        if map[tempItem.y, tempItem.x] = Wall then meetsCriteria := false;

        for item in mainList do
            if (item.x = tempItem.x) and (item.y = tempItem.y) and (item.v <= tempItem.v) then meetsCriteria := false;
       
        meetsCriteria := true;

    end;

From this procedure (shown up to the point where the error occurs):
Code: [Select]
    procedure fillStinkMap();
    var
        tempItem:       Location;
        anItem:           Location;
        scentValue:     integer = 1;
        flagComplete:  boolean = false;
        mainList:        TVector<Location>;
        tempList:        TVector<Location>;
    begin 
        //create the two lists
        mainList := TVector<Location>.create();
        tempList := TVector<Location>.create();
       
        //add start point to main list
        anItem.x := 6;
        anItem.y := 4;
        anItem.v := scentValue;
        mainList.PushBack(anItem);       
       
        while not flagComplete do
        begin
           
            //work through each item in the main list, checking adjacent cells
            for anItem in mainList do
            begin
                tempItem.x := anItem.x - 1;
                tempItem.y := anItem.y;
                tempItem.v := scentValue + 1;
               
                if meetsCriteria(tempItem, mainList) = true then
                    tempList.PushBack(tempItem);
               ...
But I get runtime error 216 from this last line. The program worked when I was using simple variables in the function call, but when I moved the definition of the lists from global scope (trying to be a good boy :D) into this procedure the error emerged. If anyone can tell me what I'm doing wrong I'd appreciate it - it's probably something silly but I've been staring at it too long! Incidentally, I thought I had to assign to Result if compiling in Delphi mode but using the function name seems to work too.
« Last Edit: July 30, 2016, 07:18:45 pm by mrguzgog »

Thaddy

  • Hero Member
  • *****
  • Posts: 10516
Re: GPF when using GVector pushback()
« Reply #1 on: July 30, 2016, 05:55:43 pm »
You might get away with a better declaration, but actually you are trying to be too good a boy... I would keep the mainlist one global and I would not use "mainlist" as a procedure variable name too. That is really bad habits.
Here's what I suggest, without testing because you didn't gave a working example ;)
I also changed the logic to avoid result not being initialized.
Code: Pascal  [Select][+][-]
  1. function meetsCriteria(const aTempItem: Location; const aMainList: TVector<Location>): boolean;
  2. var
  3.    item: Location;
  4. begin
  5.    meetsCriteria := False;
  6.    if map[aTempItem.y, aTempItem.x] <> Wall then  //wth does this map come from? <---------
  7.    begin
  8.      for item in aMainList do
  9.         if not (item.x = aTempItem.x) and (item.y = aTempItem.y) and (item.v <= aTempItem.v) then ;
  10.             meetsCriteria := true;
  11.    end;
  12. end;
  13.  
Note this still contains a bug, see comment in source. The map access seems to be neither global or local.... where does it come from.
Note the const parameter passing is really important, as is changing the names of the parameters as is the change in the logic to be consistent.

There's more to your code I find troublesome, but -without full compilable sourcecode or example - I am 99% + sure the error is not caused by the pushback, but by the meetsCriteria function


« Last Edit: July 30, 2016, 06:18:56 pm by Thaddy »

mrguzgog

  • Jr. Member
  • **
  • Posts: 71
Re: GPF when using GVector pushback()
« Reply #2 on: July 30, 2016, 06:22:15 pm »
Thanks Thaddy. Regarding the use of (duplicate) names as parameters, in this instance I thought it would just make things clearer, I wouldn't usually use the same name as the parameter.

The const issue I don't see how that helps much when according to the docs it just indicates that I won't change the value in the function.

I thing I've resolved the issue though, in part thanks to your rearranging the code - I was assuming that setting the return value of the function cause a C-like immediate return - oops! :-[  :-[  :-[

I've re-written it using exit(value) which seems to be a legitimate way to exit immediately.

The map array you queried is defined in the interface of the unit.

Thaddy

  • Hero Member
  • *****
  • Posts: 10516
Re: GPF when using GVector pushback()
« Reply #3 on: July 30, 2016, 07:08:25 pm »
Thanks Thaddy. Regarding the use of (duplicate) names as parameters, in this instance I thought it would just make things clearer, I wouldn't usually use the same name as the parameter.

The const issue I don't see how that helps much when according to the docs it just indicates that I won't change the value in the function.

I thing I've resolved the issue though, in part thanks to your rearranging the code - I was assuming that setting the return value of the function cause a C-like immediate return - oops! :-[  :-[  :-[

I've re-written it using exit(value) which seems to be a legitimate way to exit immediately.

The map array you queried is defined in the interface of the unit.

Well, const is also how you can detect which mainlist is accessed... the parameter one or the other one...
But apart from preventing you to change it, it also generates more efficient code. In the case of refcounted elements it also prevents against memory leaks because of reference counting: if it is a const parameter, the refcount won't change.
I also think that accessing a global array from inside a function is a bad idea. I would pass that array as a const parameter too. But glad it works now.

Again an [edit]:
Note that my example code does the same logic and jumps out of the code with a proper return value. I.o.w. an immediate return.
You may be under the impression your code is faster or something? It isn't.
Exit(value) DOES NOT! In pascal you have to set the return value as the function result. You have a 50% change your code works, depending on the value of the boolean ;) The generated code is just as efficient. 
« Last Edit: July 30, 2016, 08:13:48 pm by Thaddy »

mrguzgog

  • Jr. Member
  • **
  • Posts: 71
Re: GPF when using GVector pushback()
« Reply #4 on: July 30, 2016, 07:18:31 pm »
I see, thanks again.

 

TinyPortal © 2005-2018