Small error on the wiki about the substr function

Started by handsource-dyko, August 02, 2011, 08:33:28 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

handsource-dyko

Yesterday I was looking on the wiki about the substr function, and I noticed that there is a small discrepancy about the function's return type. In the header it is declared as a function that returns an int, but it actually returns a string. I just wanted to let you guys know.


SplinterGU

sorry, you are wrong... substr return string.

    { "SUBSTR"     , "SII" , TYPE_STRING, modstring_substr     },
    { "SUBSTR"     , "SI"  , TYPE_STRING, modstring_substr2    },

the C functions, return an INT because strings are an ID, an integer ID.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

handsource-dyko

O, Splinter, just a quick question though, I suspect there's a memory leak in the write_in_map and / or map_put function, I'm calling these in a process, wich itself is called within a loop of another process, but I free the resources with unload_map and delete_text(all_text).
The map and the text are freed with an ONEXIT in the process that uses and creates them.

I'm using this version: BGDI 1.0.0 (Jan  5 2011 11:01:15). (on windows xp, 32 bits). I don't know about any newer version though, maybe it could be my fault.


SplinterGU

use the last version... and send me a sample if the bug continue... I'll check it.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

handsource-dyko

#5
Tried my program with the latest version, bug still exists, it could be a design fault in my program.

This is the routine:



//-----------------------------------------------------------------------------
// Process used for displaying information about the selected instance
// This routine is called by the process instance itself.
//
// Entries: 'enetity'
//          
//-----------------------------------------------------------------------------
PROCESS cursor_tag(string entity);

PRIVATE

//int delay=5000;

int cursor_graph; cursor_file;

BEGIN
 
 
 
  // create a window
  cursor_graph=map_new(850,20,16);
     
  // give the window a color
  map_clear(cursor_file,cursor_graph,rgb(245,245,245));

  // set the file and graph
  file=cursor_file;
  graph=cursor_graph;

  // set it to scroll coordiates
  ctype=c_screen;

  // make the window semi-translucent
  flags=0;  
     
  // set the position
  x=600;
  y=10;
     
  // put it above all the other graphics
  z=-400;
 
  IF (editmode==TRUE)    
      // only print the text when an object is not currently being manipulated.
      IF (tagmessage==FALSE)  
         
         //say(entity+", x:"+father.x+", y:"+father.y+", id:"+father.id);
         ///*
         tagtext[0]=write_in_map(textfont,entity,ALIGN_CENTER_LEFT);
     tagtext[1]=write_in_map(captionfont,"x:",ALIGN_CENTER_LEFT);
     tagtext[2]=write_in_map(textfont,father.x,ALIGN_CENTER_LEFT);  
     tagtext[3]=write_in_map(captionfont,"y:",ALIGN_CENTER_LEFT);
     tagtext[4]=write_in_map(textfont,father.y,ALIGN_CENTER_LEFT);  
     tagtext[5]=write_in_map(captionfont,"id:",ALIGN_CENTER_LEFT);
     tagtext[6]=write_in_map(textfont,father.id,ALIGN_CENTER_LEFT);  
         //*/
        ///*
         map_put(cursor_file,cursor_graph,tagtext[0],30,10);          
         map_put(cursor_file,cursor_graph,tagtext[1],560,10);
         map_put(cursor_file,cursor_graph,tagtext[2],580,10);        
         map_put(cursor_file,cursor_graph,tagtext[3],660,10);
         map_put(cursor_file,cursor_graph,tagtext[4],680,10);        
         map_put(cursor_file,cursor_graph,tagtext[5],750,10);
         map_put(cursor_file,cursor_graph,tagtext[6],780,10);
          //*/      
     FRAME;
      END      
  END
 
  IF (editmode==FALSE)
     LOOP
        FRAME;
     END
  END
 
ONEXIT

  // free memory
  delete_text(all_text);
  unload_map(cursor_file,cursor_graph);  
 
  //say("cursotag id: "+id+" ended.");  
END




The above routine is called in a loop , for instance, by a enemy or object routine like this bear routine:



//-----------------------------------------------------------------------------
// Process used to put bears' objects
// Entries:  'x' 'y' Objects' coordinates
//           'incr_x' Horizontal increment (to the left and right)
//-----------------------------------------------------------------------------

PROCESS bear(x,y,incr_x,count);  

PRIVATE
int tag;

BEGIN
   //file=game.fpgfile;
   
   // load the graphics file
   file=game.bear.fpgfile;
   
   graph=game.bear.first_frame; // Number of graphic
   ctype=c_scroll;              // Puts it within scroll


IF (editmode==TRUE)
  // display a tagbox around the graph
      tagbox(file,x,y,graphic_info(file,graph,G_WIDTH),graphic_info(file,graph,G_HEIGHT),BROWN);
   
      // display the controlpoint for the center
      controlpoint(file,graph,x,y,graphic_info(file,graph,G_WIDTH),graphic_info(file,graph,G_HEIGHT));
END


   LOOP
       IF (editmode==FALSE)
       
           // Plays a bear sound from time to time (randomly)
           IF (rand(0,48)==0)
              play_sound(s_bear,50,256);
           END
           x+=incr_x;             // Moves graphic horizontally

           // If the end of platform has been reached
           IF (NOT on_screen())
               incr_x=-incr_x;        // Changes horizontal increment
               x+=incr_x*2;           // Moves the graphic a little bit
               // Turns graphic to the opposite side
               IF (flags==0)
                   flags=1;
               ELSE
                   flags=0;
               END
           END

           // Plays graphics' animation
           graph++;
           IF (graph>game.bear.last_frame)
              graph=game.bear.first_frame;
           END
           
       END // end of editmode selector


IF (editmode==TRUE)
  IF (collision(TYPE cursor) AND working==FALSE)
                      tag=cursor_tag("selected entity: Bear "+count);                      
                 END
      END
       
       FRAME;
   END
END




It is one of the last parts in the loop.
I know that the cursor_tag process is invoked in every iteration of the loop, but cursor_tag ends in every iteration and the onexit
part works, since I tested it with a say() text. Anyway, I noticed that my program keeps using more memory when the hand cursor
in mapedit is colliding with an object, and I deducted it to cursor tag routine. When I uncommend the map_put and write_in_map parts,
it doesn't seem to happen. Also, when I move the cursor away (it's no longer colliding), the memory allocation stops, but it isn't freed.

The cursor routine is quite big, it consists of serval files, and I have already checked/fixed other parts of it that where suspicious.

Just a thought, is map_put really suitable to such extensive use in a loop? In an older version I simply used write(), but I had some glitches with that. It's not really a mayor problem, but just a glitch that cought my attention.

Here's an archieve with 4 tar archives inside, just unpack them in the numbered order, starting with number 1, run me.bat or sme.bat
And move the cursor on an object and check monitor bgdi's memory usage in the task manager.

http://www.megaupload.com/?d=7ICPG0YJ

SplinterGU

please, give me an isolate sample with the bug.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

handsource-dyko

I know it's more conveint to isolate it, but the problem is that it's not so easy to isolate. The problem is best seen when the program is run, maybe I missed something or refered to an incorrect identifier. The cursor_tag routine creates maps in memory, and uses a local variable for the map and file identifiers, instead of the systemfile. Maybe this could be the reason? I'll try a few more things out.

SplinterGU

you said... "I suspect there's a memory leak in the write_in_map and / or map_put function"... well, I'll glad if you send me an example with this functions that show the error.

please, thanks.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

oh, you must unload_map of

tagtext[0]
tagtext[1]
tagtext[...]
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

I don't understand why you do write_in_map and map_put if you destroy it in onexit and no loop for edit_mode == true.

map_new create a map in system lib (0), don't use cursor_file for access to var create with map_new
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

handsource-dyko

Thanks!  ;) It fixed it. Stupid me. I only had to add these lines:


unload_map(0,tagtext[0]);
unload_map(0,tagtext[1]);
unload_map(0,tagtext[2]);
unload_map(0,tagtext[3]);
unload_map(0,tagtext[4]);
unload_map(0,tagtext[5]);
unload_map(0,tagtext[6]);


That was a very simple error that I overlooked. :D


SplinterGU

Download Lastest BennuGD Release: http://www.bennugd.org/node/2