code with mem allocation seems to work proper when it shouldn't

Started by Rainstorm, April 10, 2008, 03:10:49 PM

Previous topic - Next topic

Rainstorm

This code is supposed to scan a txt file & report the line numbers & their sizes (amount of chars in a line) above the specified number. It stores the results in 2 buffers allocated using Heapalloc & reallocates more memory if needed. - when i looked again at the allocaton functions I realised that I had specified just the additional bytes i wanted... instead of the whole new size (oldbuffsize + additionalamount).
For eg if  my old buffer was 512 & I needed 256bytes more i should specify 768 for reallocation, but I've just specified 256 bytes

The code still seems to work proper though.. & all the results seem to be shown inspite of several reallocations taking place. Can someone tell me why this is happening ? My old results should be overwritten or something... since its the same block without more memory & probably reduced in size
I've used 'Console assemble & link', not tested it out that much

[EDIT] Alaso is there no need of creating 2 heap abjects with HeapCreate, OR should i just create one heap object & allocate the seperate blocks needed (using 'HeapAlloc') from that one mem object ??
would appreciate any feedback on this..

Thank you
=================================

    .const
        HEAP_CREATE_ENABLE_EXECUTE      equ     262144


    .data?


    .data
        pfname                      dd      0
        flen                        dd      0
        fpattern                    db      "text files",0,"*.txt",0,0
        total_characters_in_line    dd      0
        pfbuff                      dd      0
        line_char_limit             dd      0
        pline_char_limit            dd      0
        hInstance                   dd      0
       
        hHeap_line                  dd      0
        hHeap_linecharcount         dd      0
        p_linecount_buff            dd      0
        p_linecharcount_buff        dd      0

        ptop_linecount_buff         dd      0
        ptop_linecharcount_buff     dd      0
        linebuffer_usedbytes        dd      0
        charbuffer_usedbytes        dd      0
        linebuff_size               dd      0
        line_charcountbuff_size     dd      0
        total_matchinglines_found   dd      0       
        total_lines                 dd      0
        temp                        dd      0


; -----------------------------------------------------------------------


    .code

start:

    invoke GetModuleHandle, NULL      ; get the handle of this program
    mov hInstance, eax

    mov pfname,  OpenFileDlg(NULL,hInstance,"Select File",addr fpattern)
    cmp BYTE PTR [eax], 0
    je exit_

   
    invoke read_disk_file,pfname,addr pfbuff, addr flen 
    cmp eax, 0
    je exit_

    print "returned file length - "
    print ustr$(flen),13,10

   ; ------- // Input the character limit // ---------

    mov pline_char_limit, input("enter the max character count of line",58)
   
    mov line_char_limit, uval(pline_char_limit)
    print "pause.. - character Limit - : "
    print ustr$(line_char_limit),13,10

;      mov eax, pfbuff
;      mov byte ptr [eax+flen-1], 0          ; add a NULL at the eof in the buffer



;     ------ //  Create the memory heap & Allocate Memory  // --------

    ; ----------------------------------
    ;  create buffer for line numbers
    ; ----------------------------------
   
      invoke HeapCreate, HEAP_CREATE_ENABLE_EXECUTE or HEAP_NO_SERIALIZE, 0, 0
        cmp eax, 0
        je heap_creation_error
        mov hHeap_line, eax                 ; handle to memory object

      invoke HeapAlloc, hHeap_line, HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY, 512
        cmp eax, 0
        je heap_allocation_error
        mov p_linecount_buff, eax           ; pointer to allocated block
        mov ptop_linecount_buff, eax
       
      invoke HeapSize, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff

        cmp eax, 4294967295                 ; tests if the size function succeeded
        je heap_size_error                 
        mov linebuff_size, eax              ; store the size


    ; ----------------------------------------------
    ;  create buffer for the character count of the lines
    ; ----------------------------------------------

      invoke HeapCreate, HEAP_CREATE_ENABLE_EXECUTE or HEAP_NO_SERIALIZE, 0, 0
        cmp eax, 0
        je heap_creation_error
        mov hHeap_linecharcount, eax             ; handle to memory object

      invoke HeapAlloc, hHeap_linecharcount, HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY, 512
        cmp eax, 0
        je heap_allocation_error
        mov p_linecharcount_buff, eax            ; pointer to allocated block
        mov ptop_linecharcount_buff, eax

      invoke HeapSize, hHeap_linecharcount, HEAP_NO_SERIALIZE, p_linecharcount_buff

        cmp eax, 4294967295
        je heap_size_error
        mov line_charcountbuff_size, eax
   

   ; -----------------------------------------------


        mov esi, pfbuff                     ; move address of the file buffer into esi
        xor ecx, ecx
        xor ebx, ebx
        jmp count_characters
 
    pre_count:
         xor ecx, ecx                        ; reset count of chars in the line
         add esi, 1
       
      count_characters:
          cmp byte ptr [esi], 0
          je display_results       
          cmp byte ptr [esi], 10
          je newline
          inc esi                           ; pointer to file buffer
          add ecx, 1                        ; count of characters in the line
          jmp count_characters

    newline:
;         add ecx, 1                        ; would count the 'LF' too
          add total_lines, 1                ; total line count
          mov total_characters_in_line, ecx
          cmp ecx, line_char_limit    ; cmp the total chars in the line with the requested limit
          jb pre_count
          add total_matchinglines_found, 1


comment * -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
          else check to see if the memory buffer is full
          if so, reallocate more memory
          else add the character count & line number to the buffer
        -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - *


    ; ---- / check if there's enough space in the buffers / -----

          mov eax, ptop_linecount_buff
          sub eax, p_linecount_buff         ; subtract base addr from top addr
          mov linebuffer_usedbytes, eax
          mov edx, linebuff_size
          sub edx, 16                       ; check at 16 bytes ahead of time
          cmp edx, eax                      ; cmp no. of used bytes with the buffer size
          jbe reallocate_linecount_buff
          call store_linenumber


       check_line_charcount_buffer:

          mov eax, ptop_linecharcount_buff
          sub eax, p_linecharcount_buff
          mov charbuffer_usedbytes, eax
          mov edx, line_charcountbuff_size
          sub edx, 16                       ; reallocate 16 bytes ahead of time
          cmp edx, eax
          jbe reallocate_charcount_buff
          call store_line_charcount
          jmp pre_count

         

    ; ---- / add the line number & character count of the line to the buffers / -----


       store_linenumber:

          mov eax, total_lines                  ; the line number
          mov edx, ptop_linecount_buff
          mov [edx], eax                        ; move the count of chars into the buffer
          add ptop_linecount_buff, 4            ; track the top of the buffer

         ret

       store_line_charcount:
       
          mov ecx, total_characters_in_line
          mov edx, ptop_linecharcount_buff
          mov [edx], ecx                         ; move the line count in the buffer
          add ptop_linecharcount_buff, 4         ; track the top of the linecount buffer
         ret 


    ; ----------- //  Reallocate Memory  //ffff ---------------

    reallocate_linecount_buff:
     
      invoke HeapReAlloc, hHeap_line,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,
                          p_linecount_buff, 256

        cmp eax, 0
        je heap_reallocation_error
        mov p_linecount_buff, eax              ; pointer to reallocated block



      invoke HeapSize, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff

        cmp eax, 4294967295                    ; test if the size function succeeded
        je heap_size_error
        mov linebuff_size, eax   

     
        mov eax, linebuffer_usedbytes
        add eax, p_linecount_buff
        mov ptop_linecount_buff, eax
        call store_linenumber
        jmp check_line_charcount_buffer

    ;-------------------------------------------------

    reallocate_charcount_buff:   
      invoke HeapReAlloc, hHeap_linecharcount,HEAP_NO_SERIALIZE or HEAP_ZERO_MEMORY,
                          p_linecharcount_buff, 256

        cmp eax, 0
        je heap_reallocation_error
        mov p_linecharcount_buff, eax       ; pointer to reallocated block

      invoke HeapSize, hHeap_linecharcount, HEAP_NO_SERIALIZE, p_linecharcount_buff

        cmp eax, 4294967295                 ; test if the size function succeeded
        je heap_size_error
        mov line_charcountbuff_size, eax              ; store the size


        mov eax, charbuffer_usedbytes       
        add eax, p_linecharcount_buff       ; bring the pointer in the new block..
        mov ptop_linecharcount_buff, eax    ; to where it was in the data before..
        call store_line_charcount           ; reallocation.
        jmp pre_count



  ;---------------------------------------------------------------------   
  ;                display the results
  ;         ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

        display_results:
          print " ",13,10,
          print "Filename : "
          print pfname,13,10
          print "Total Lines: "
          print ustr$(total_lines),13,10
          inkey
          print " ",13,10,
          print "Lines with a character count equal to or above "
          print ustr$(line_char_limit)
          print "  =  "
          print ustr$(total_matchinglines_found),13,10
          print "=============================================",13,10

          mov edi, p_linecount_buff
          mov edx, ptop_linecount_buff     
          mov dword ptr [edx+1], 0            ; add a 0 at the top of the buffer

;    --//  display the line numbers //
           
        display_results1:
          mov ebx, dword ptr [edi]
          print ustr$(ebx)
          print ", "
          add edi, 4
          cmp dword ptr [edi], 0
          jne display_results1

          print " ",13,10,
          print "=============================================",13,10
          print " ",13,10,
      inkey
      print " ",13,10,13,10
      print "lines with corresponding character counts equal\
             to or above the requested limit",13,10

      print "=============================================",13,10

          mov edi, p_linecount_buff
          mov edx, ptop_linecount_buff     ; add a 0 at the top of the buffer
          mov dword ptr [edx+1], 0

          mov esi, p_linecharcount_buff
          mov edx, ptop_linecharcount_buff
          mov dword ptr [edx+1], 0

comment * -------------------------------------------------------   
            Display the line numbers with the corresponding char
            counts of the lines
          ------------------------------------------------------- *   

        display_results2:
          mov ebx, [edi]
          print ustr$(ebx)
          print " -  "
          mov ebx, [esi]
          print ustr$(ebx),13,10
          add edi, 4
          add esi, 4
          cmp dword ptr [edi], 0
          jne display_results2
         
      print " ",13,10,
      print "=============================================",13,10

      print "finished",13,10,13,10
      jmp free_memory


   ; ----------- //  Errors  //------------------------------------------

    heap_creation_error:
         print "memory error: memory heap couldn't be created",10,13
         jmp exit_

    heap_allocation_error:
         print "memory error: memory couldn't be allocated",10,13
         jmp exit_
         
    heap_reallocation_error:
         print "memory error: memory couldn't be reallocated",10,13
         jmp free_memory
         
    heap_size_error:
         print "memory error: heap size error",10,13
         jmp exit_

   ; ---------------------------------------------------------------------

    free_memory:

        free pfbuff
        free pfname
       
        invoke HeapFree, hHeap_line, HEAP_NO_SERIALIZE, p_linecount_buff
            cmp eax, 0
            jne @F
        print "HeapFree error !",13,10

      @@:
        invoke HeapFree, hHeap_linecharcount,HEAP_NO_SERIALIZE,p_linecharcount_buff
            cmp eax, 0
            jne @F
        print "HeapFree error !",13,10
            jmp exit_


     @@:
        print "Memory successfully freed",13,10


    exit_:
         inkey "press any key to exit..."
         exit


end start

hutch--

rainstorm,

I just downloaded your test piece and it seems to work fine, I tested it on windows.inc with a bottom cut off of 64 bytes.

Compliments, your code is clear, well written and properly commented.  :U

Now if you are brave, post it in the Laboratory to see if anyone can help you get it faster.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

xmetal

The code will work, as long as it does not reach the boundary of the allocated page. If it reaches the boundary, it will overwrite the "housekeeping" structures used by Windows, and after crossing the boundary, it will generate an exception.

Rainstorm

Quoterainstorm,

I just downloaded your test piece and it seems to work fine, I tested it on windows.inc with a bottom cut off of 64 bytes.
Compliments, your code is clear, well written and properly commented.  ThumbsUp
Now if you are brave, post it in the Laboratory to see if anyone can help you get it faster.

Hutch,  Thanks.
   I'll make the changes to the buffer allocation & give it a try.

-

Rainstorm

xmetal wrote..
QuoteThe code will work, as long as it does not reach the boundary of the allocated page. If it reaches the boundary, it will overwrite the "housekeeping" structures used by Windows, and after crossing the boundary, it will generate an exception

xmetal, thanks for the explanation. I take that to mean that my allocations are all smaller than a page in this case, so the size of a page of memory gets allocated anyhow & that's why the code worked..- it left me bewildered for a bit.

thankyou

Rainstorm.

jj2007

Test the page boundaries! On my puter (XP SP1) it fails at 566 bytes...

MyTest proc
LOCAL StartBuf:DWORD
lea edx, StartBuf
xor ecx, ecx
mov eax, ecx
.While ecx<1024
.if ecx>560
Message str$(ecx)
.endif
mov [edx], al
inc edx
inc ecx
.Endw
Message chr$("OK")
ret
MyTest endp

Rainstorm

bit confused, isn't a page supposed to be 4K or something ?

jj2007

Quote from: Rainstorm on April 14, 2008, 01:31:04 AM
bit confused, isn't a page supposed to be 4K or something ?
indeed - me confused, too. 566 is something like 2^9.14  :wink
Do you get the same result?