News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

VirtualFree

Started by ragdog, July 11, 2010, 05:04:12 PM

Previous topic - Next topic

asmfan

a hint: use MEM_COMMIT and MEM_RESERVE together, if MEM_RESERVE wasn't used previously. Then MEM_RELEASE will do its job fine.
Russia is a weird place

ragdog

Thanks I comming not further with it

I have change to

invoke VirtualAlloc,0,eax,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax
...
..

invoke VirtualFree, pszMem,nSize,MEM_RELEASE
    .if (eax!=0)
        invoke    MessageBox,0,CTEXT ("The memory is free"),0,MB_OK
     .else
          invoke    MessageBox,0,CTEXT ("The memory is not free"),0,MB_OK
    .endif

With same result :red

Can you post me an example?

oex

Quote from: ragdog on July 18, 2010, 06:36:31 PM
invoke VirtualFree, pszMem,nSize,MEM_RELEASE

If you specify this value, dwSize must be 0 (zero)



invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax

invoke VirtualFree, pszMem,0,MEM_RELEASE

print str$(eax)
inkey

eax prints '1'
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

ragdog

Thanks

Now have i found this bug i have no idea why and how i can solve it

If the pszMem filled from GetWindowText  cannot free it

invoke    GetWindowText,hWnd,addr pszMem,nSize

I have try bevore i use VirtualFree ,use RtlZeroMemory without good result


oex

I dont use windows controls but surely this would work?


invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax

invoke GetWindowText,hWnd,pszMem,nSize <---- Note not 'ADDR pszMem'

invoke VirtualFree, pszMem,0,MEM_RELEASE

Where nSize is the number of characters you want to copy
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

ragdog

Quote
invoke GetWindowText,hWnd,pszMem,nSize <---- Note not 'ADDR pszMem'

Without use addr works this VirtualFree

But I cannot get the text from edit control :wink


Gives a other way with other alloc apis?

MichaelW

#21
The functions all appear to work the way they are documented to work.

;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        pMem dd 0
    .code
;==============================================================================
ShowState proc ptrMem:DWORD
    LOCAL mbi:MEMORY_BASIC_INFORMATION
    invoke VirtualQuery, ptrMem, ADDR mbi, SIZEOF mbi
    SWITCH mbi.State
      CASE MEM_COMMIT
        print "MEM_COMMIT",13,10
      CASE MEM_FREE
        print "MEM_FREE",13,10
      CASE MEM_RESERVE
        print "MEM_RESERVE",13,10
    ENDSW
    ret
ShowState endp
;==============================================================================
start:
;==============================================================================
    invoke ShowState, pMem

    invoke VirtualAlloc, NULL, 1024, MEM_COMMIT, PAGE_READWRITE
    mov pMem, eax
    .IF eax == 0
        print LastError$(),13,10
    .ENDIF

    invoke ShowState, pMem

    invoke VirtualFree, pMem, 0, MEM_RELEASE
    .IF eax == 0
        print LastError$(),13,10
    .ENDIF

    invoke ShowState, pMem

    invoke VirtualAlloc, NULL, 1024, MEM_RESERVE, PAGE_READWRITE
    mov pMem, eax
    .IF eax == 0
        print LastError$(),13,10
    .ENDIF

    invoke ShowState, pMem

    invoke VirtualFree, pMem, 0, MEM_DECOMMIT
    .IF eax == 0
        print LastError$(),13,10
    .ENDIF

    invoke ShowState, pMem

    invoke VirtualFree, pMem, 0, MEM_RELEASE
    .IF eax == 0
        print LastError$(),13,10
    .ENDIF

    invoke ShowState, pMem

    inkey "Press any key to exit..."
    exit
;==============================================================================
end start

typedef struct _MEMORY_BASIC_INFORMATION {
  PVOID BaseAddress;
  PVOID AllocationBase;
  DWORD AllocationProtect;
  SIZE_T RegionSize;
  DWORD State;
  DWORD Protect;
  DWORD Type;
} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;


MEM_FREE
MEM_COMMIT
MEM_FREE
MEM_RESERVE
MEM_RESERVE
MEM_FREE


And the same for this code:

;==============================================================================
; Build as console app so print can display.
;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================

IDC_EDIT  equ 101
IDC_BTNU  equ 102
IDC_BTNL  equ 103

;==============================================================================
    .data
      hInstance     dd 0
      hwndEdit      dd 0
    .code
;==============================================================================

DlgProc proc hwndDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD

    LOCAL pMem:DWORD, tLength:DWORD

    SWITCH uMsg

        CASE WM_INITDIALOG

            invoke GetDlgItem, hwndDlg, IDC_EDIT
            mov hwndEdit, eax

        CASE WM_COMMAND

            SWITCH wParam

                CASE IDC_BTNU

                    invoke GetWindowTextLength, hwndEdit
                    inc eax
                    mov tLength, eax
                    print str$(eax),13,10
                    invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
                    mov pMem, eax
                    print hex$(eax),13,10
                    invoke GetWindowText, hwndEdit, pMem, tLength
                    print str$(eax),13,10
                    invoke crt__strupr, pMem
                    print hex$(eax),13,10
                    invoke SetWindowText, hwndEdit, pMem
                    print str$(eax),13,10
                    invoke VirtualFree, pMem, 0, MEM_RELEASE
                    print str$(eax),13,10,13,10


                CASE IDC_BTNL

                    invoke GetWindowTextLength, hwndEdit
                    inc eax
                    mov tLength, eax
                    print str$(eax),13,10
                    invoke VirtualAlloc, NULL, eax, MEM_COMMIT, PAGE_READWRITE
                    mov pMem, eax
                    print hex$(eax),13,10
                    invoke GetWindowText, hwndEdit, pMem, tLength
                    print str$(eax),13,10
                    invoke crt__strlwr, pMem
                    print hex$(eax),13,10
                    invoke SetWindowText, hwndEdit, pMem
                    print str$(eax),13,10
                    invoke VirtualFree, pMem, 0, MEM_RELEASE
                    print str$(eax),13,10,13,10

                CASE IDCANCEL

                    invoke EndDialog, hwndDlg, 0

            ENDSW

        CASE WM_CLOSE

            invoke EndDialog, hwndDlg, 0

    ENDSW

    xor   eax, eax
    ret

DlgProc endp

;==============================================================================
start:
;==============================================================================

    invoke GetModuleHandle, NULL
    mov   hInstance, eax

    Dialog "Test", \
           "MS Sans Serif",10, \
           WS_OVERLAPPED or WS_SYSMENU or DS_CENTER, \
           3,0,0,130,110,1024

    DlgEdit WS_BORDER or ES_MULTILINE or ES_WANTRETURN or \
            WS_VSCROLL or WS_HSCROLL or ES_AUTOVSCROLL or ES_AUTOHSCROLL, \
            7,7,113,65,IDC_EDIT

    DlgButton "UCASE",0,28,82,30,10,IDC_BTNU
    DlgButton "LCASE",0,68,82,30,10,IDC_BTNL

    CallModalDialog hInstance,0,DlgProc,NULL

    exit
;==============================================================================
end start

eschew obfuscation

ragdog

Hi

My problem is solved and works fine

Now have i a other question to allocate memory

I need for my project more allocate memory for use 2 buffers!

I know as one might call this function 2 times .
My thinking is a other way to not use 2 times this function


My steps:

invoke VirtualAlloc,NULL,1000...
.if (eax)
mov    pszMem,eax ;pszMem is now 1000 bytes reserved

mov pszMem2,eax ;[eax /2]

.endif

Now have i in pszMem2 500 bytes or?

And by VirtualFree
VirtualFree,pszMem,1000,MEM_DECOMMIT

Now is pszMem and pszMem2 free

Could this work?




jj2007

.if (eax)
mov    pszMem,eax ;pszMem is now 1000 bytes reserved
add eax, 500   ; NOW you have 2*500 bytes of buffer
mov pszMem2,eax ;[eax /2]

.endif

ragdog

Thanks for your post

I hope i understand this correct ::)
mov pszMem,eax ;is the pointer to the allocated memory with 1000 bytes
add eax, 500      ;add to this pointer 500
mov pszMem2,eax

Then have i in pszMem 500 bytes and in pszMem2 500bytes?

Why say you  2*500 bytes of buffer?

Greets

dedndave

2 x 500 = 1000

you are allocating 1000 bytes and splitting it into two 500-byte buffers

when you free the allocated block, you will only need to free the original 1000-byte block base address (handle)

KeepingRealBusy

Quote from: oex on July 18, 2010, 06:57:56 PM
Quote from: ragdog on July 18, 2010, 06:36:31 PM
invoke VirtualFree, pszMem,nSize,MEM_RELEASE

If you specify this value, dwSize must be 0 (zero)



invoke VirtualAlloc,0,8192,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
mov pszMem,eax

invoke VirtualFree, pszMem,0,MEM_RELEASE

print str$(eax)
inkey

eax prints '1'

This is what I always use. I allocate a huge hunk, then completely free it when I am done.

Dave.

redskull

Just for the record, it's rather fruitless to reserve anything less than 64k of memory using VirtualAlloc; While windows will reserve things 4K at a time, it positions them on 64K aligned boundaries.  Consequently, reserving less than that essentially wastes all the other address space, which can never be used.  To be totally optimal, you should reserve 64K chunks of address space at a time, and then commit them 4K at a time, as needed.  If you have lots of smaller allocations, the heap is a more convienent option

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government

KeepingRealBusy

Quote from: redskull on July 25, 2010, 07:09:48 PM
Just for the record, it's rather fruitless to reserve anything less than 64k of memory using VirtualAlloc; While windows will reserve things 4K at a time, it positions them on 64K aligned boundaries.  Consequently, reserving less than that essentially wastes all the other address space, which can never be used.  To be totally optimal, you should reserve 64K chunks of address space at a time, and then commit them 4K at a time, as needed.  If you have lots of smaller allocations, the heap is a more convienent option

-r

The following is a map of all of the memory I can allocate in one of my programs:


                                                Base        Size        End
Bases

0x004075C7  00 00 41 00                     ;   41000000    7c3f0000    BD3F0000
0x004075CB  00 00 b2 7c                     ;   7cb20000    02bd0000    7F6F0000
0x004075CF  00 00 7f 7f                     ;   7f7f0000    007bf000    7FFAF000
0x004075D3  00 00 32 00                     ;   00320000    000df000    3FF000
0x004075D7  00 00 00 00                     ;   
0x004075DB  00 00 00 00                     ;   
0x004075DF  00 00 00 00                     ;   
0x004075E3  00 00 00 00                     ;   
0x004075E7  00 00 00 00                     ;   
0x004075EB  00 00 00 00                     ;

                                                Size
Sizes

0x004075EF  00 00 3f 7c                     ;   7c3f0000
0x004075F3  00 00 bd 02                     ;   02bd0000
0x004075F7  00 f0 7b 00                     ;   007bf000
0x004075FB  00 f0 0d 00                     ;   000df000
0x004075FF  00 00 00 00                     ;   
0x00407603  00 00 00 00                     ;   


You will notice that the last 2 allocations are not mod 64K in size, in fact they are mod 4K. I allocate these by trying to get the biggest piece I can, then saving the base and size. Then I try again up to 9 more times, getting smaller and smaller pieces.

If I limited myself to 64K sized requests, I would not get the 30 4K blocks (f000 of 007bf000) and (f000 of 000df000).

To be sure, you need to temper this. I allocated all available memory then forced an error (load from location 0). The program terminated with no message. I then started allocating space between the first and subsequent allocations with a 4K block, and freed the special space after I got the last available block, then I tried the bad access. I grew this special block until Visual Studio could be brought in to report the error. I then hardcoded this special size. I now get the biggest piece, the special block, then the remaining space, then free the special block. No more problems.

Dave.

redskull

The size of existing allocations is not related to the allocation granularity; it's the BASE that is configured to mod 64k.  For example, the allocation at 320000 is base 64K, and the 'end' is at 003FF000.  That means all the address space between 003FF001 and 040000 is now both inaccessible and unallocable.

-r
Strange women, lying in ponds, distributing swords, is no basis for a system of government