Announcement

Collapse
No announcement yet.

mem_Free

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • mem_Free

    I have been working with mem_Free function to deallocate memory blocks created with file_LoadFunction and mem_Alloc functions. Allocations and deallocations all work fine, but according to the manual, the mem_Free function should return TRUE if successfull and FALSE if deallocation fails. According to my tests, this is not the case and the function returns values 0, 2, 3 or 4. Also, if the function is suppose to fail, there is a change in the memory heap.

    If I do everything correctly, all the functions work fine, but especially if I do something wrong, the replies are a bit beyond a simple TRUE and FALSE. Can you explain what is the meaning of these return values? Also, if there is a problem, the function is able to detect it and returns 3 instead of 2, but still changes some memory?

    Also, what will happen, if I try to deallocate a static function (not dynamically loaded with file_LoadFunction). Will these result just in a mem_Free failed result or will it mess up my memory?

    Regards,
    Valentin


    #platform "uLCD-32PT_GFX2"
    func main()
    var t;
    gfx_ScreenMode(4);

    print("Heap before allocation: ", mem_Heap(),"n"); //prints 13752 (OK)

    t:=mem_Alloc(2000);

    print("Heap after allocation: ",mem_Heap(),"n"); //prints 11748 (OK)
    print("Successful dealocation: ", mem_Free(t),"n"); //prints 2 (OK, should be 1, but it is still TRUE)
    print("Heap after deallocation: ",mem_Heap(),"n"); //prints 13752 (OK)
    print("Second dealocation: ", mem_Free(t),"n"); //prints 3 (?? should fail?)
    print("Heap after second deallocation: ",mem_Heap(),"n"); //prints 13224 (?? where have 528 bytes go?)
    print("Deallocating 0 pointer: ",mem_Free(0),"n"); //prints 0 (OK)
    print("Heap after 0 deallocation: ",mem_Heap(),"n"); //prints 12312 (?? another 912 bytes missing?)
    print("Deallocating -1 pointer: ",mem_Free(-1),"n"); //prints 4 (??)
    print("Heap after -1 deallocation: ",mem_Heap(),"n"); //prints 13752 (OK all missing bytes are back?)

    repeat forever
    endfunc

  • #2
    Yes it does return other values, but generally, FALSE = 0, TRUE = non zero.

    The other values returned are useful at times to understand the way the heap works:-

    0 = failed , the heap chain could not be validated, generally considered to be a non recoverable major failure
    1 = was only 1 block, now none (you'll never get this, system uses mem before user prog....)
    2 = garbage collect (merged last)
    3 = simple release of block
    4 = freed ALL

    Any attempt to free anything that has not been formally allocated will mess things up.

    It is also important to know that mem_Free will return TRUE if it was happy with what it did (which may have smashed the heap if it was not a valid allocation)

    One of the most common problems is freeing something twice, this will break it but generate no error.

    Also note that the heap works downwards, starting from the top of internal RAM, and mem_Heap returns the size of the largest block available - not the actual byte count available in the heap.

    The format of the chains in the heap are:-

    a := mem_Alloc(20);

    a-2 pointer to next block (word)
    a-1 size of allocated block (word)
    a block[] <<< mem_Alloc returns pointer to here.

    here is a bit of a test to show whats going on

    func main()
    gfx_Cls();

    #constant TEST 0 //1
    var n,m;
    print("Heap = ",mem_Heap(),"\n"); // gives 100

    n := mem_Alloc(100);
    m := mem_Alloc(200);
    print("m= ",m," n=",n,"\n"); // show allocation addresses


    print("Heap now ",mem_Heap(),"\n"); // gives 100

    print("sizeof n ",n[-1],"\n"); // gives 100
    //print(n[-2],"\n"); // not readable, returns 0

    print("sizeof m ",m[-1],"\n"); // gives 200
    //print(m[-2],"\n\n"); // not readable, returns 0

    #IF TEST == 1
    // release first block first
    print(mem_Free(n),"\n"); // result = 3
    print(mem_Free(m),"\n"); // result = 2
    #ELSE
    // release first block last
    print(mem_Free(m),"\n"); // result = 2
    print(mem_Free(n),"\n"); // result = 2
    #ENDIF

    print("Heap finally ",mem_Heap(),"\n");


    repeat forever

    endfunc

    Regards,
    Dave

    Comment


    • #3


      Thanks Dave,

      this makes much more sense now. I have just one more question. How can a-2 (pointer to next block) always read zero (you have commented it as not readable)? I would expect that it would be zero for the last block, but not for the others.

      Regards,
      Valentin

      Comment


      • #4


        It is simply protected from reading or writing.

        Reason is that it is a 'real' pointer, and not relevant to the 'virtual' addresses used in the run time.
        Regards,
        Dave

        Comment


        • #5


          Hello:

          I have a question regarding a problem I am having returning from a sub program. I call a sub-program
          like this:
          (hFile);

          Comment


          • #6


            The memory used by the program itself will not be freed until the sub program exists, see how much memory you have free at that point
            Mark

            Comment


            • #7


              Ok, I understand, but when I hit the button to return, the screen blinks and resets and it gives me the ram available after the reset. I tried pause (1000) so I could see how much ram was freed up before it reset but that didn't work. I'm stumped by what could be causing it to reset, I tried making the sub-program much smaller and tried calling the sub from a much smaller (less than 2000 bytes) main program, but that didn't make any difference.
              What else beside availability of ram could cause it to reset? I remember reading that the program returns back from wherever it was launched. Does that mean from the main() where the button presses are read? or from the function that calls the subprogram? There are no error codes to go by. Is there a step by step debugger or edit log that I can download or turn on?

              Thanks for any help you can give me.

              Mark

              Comment


              • #8


                Most common problem is setting some sort of event handler in the sub program (comms, timer, etc.) and not resetting it / turning it off before returning.

                Saw one the other day where memory was freed in the sub program (memory passed from main program) and then the main program tried to use it.

                Print/Pause is the way I normally try to locate the issue.

                Serout often helps too, as the pause isn't needed.
                Mark

                Comment


                • #9


                  Hi there,

                  I am using the following pointer table:
                  E_vector[0]:=&E_WatchDog;
                  E_vector[1]:=&E_EmgSeq;
                  E_vector[2]:=&E_Drivers;
                  ...
                  E_vector[18]:=&E_Reset_CAN;
                  E_vector[19]:=&E_NoLoad;

                  Every position is pointing a given variable previously defined as var:
                  var E_WatchDog:=0;
                  var E_EmgSeq:=0;
                  var E_Drivers:=0;
                  ...
                  var E_Reset_CAN:=0;
                  var E_NoLoad:=0;

                  The pointer table is defined as follows:
                  var *E_vector[20];

                  I found some problems when trying to read a value through the pointer (*E_vector[i]). However, I can check that by using the variable itself and I get the right value. This happens only with three of the 20 elements in the table. Could be something related to the pointer pointing to a different address? Could it be related to a memory problem?

                  Best regards,

                  Jordi

                  Comment


                  • #10


                    There are no known issues in this area based on what you have posted.

                    What sort of problems have you found?

                    Can you post some code that shows how you are accessing and manipulating these variables?

                    It seems odd to have a variable that is a (constant) pointer to a variable
                    Mark

                    Comment

                    Working...
                    X