VirtualAlloc

First i would like to say that this forum is great.
am currently learning most of it on my own, c++ and the win32 api.
so to my problem:

am looking inside this api VirtualAlloc and am trying to achieve the following:
- Reserve 40 megs of virtual memory and commit 10 megs from it.
- Then i want to fill strings inside the commited memory.

am looking at api on msdn:http://msdn.microsoft.com/en-us/library/windows/desktop/aa366887(v=vs.85).aspx

my sample code:

int main()
{
int p0 = (int) VirtualAlloc(NULL,40*1024*1024 ,MEM_RESERVE,PAGE_READWRITE);;
int p1 = (int) VirtualAlloc(NULL,10*1024*1024 ,MEM_COMMIT ,PAGE_READWRITE);;


system("pause");
}

when i looked at task manager commited i get only 30 megs instead of 40 megs.
i tried changing the values ,but seems am missing something here.
what am i doing wrong here?
and how do i put repeated string in the commited area?

again thank you all and appriciate the help here.



Use perfmon (or Process Explorer from SysInternals) and monitor the appliction's Private Bytes. Task Manager can be a bit misleading .
Indeed missleading.

any idea how can i put strings in this memory commited location?
thanks for the quick reply btw.
You can use strcpy to copy a string into the buffer.

You should realise:
1. VirtualAlloc is the raw allocator in Windows. You shouldn't use it unless you intend to suballocate from it. It allocates full pages, so allocates multiples of 4K.
2. As VirtualAlloc allocates a buffer, it returns void* (LPVOID in Windows speak), thus treating that value as an int as you have done is incorrect.
i understand,
do you know where i can find a sample that is doing the above so i could learn from it :
- Reserve 40 megs of virtual memory and commit 10 megs from it.
- Then i want to fill strings inside the commited memory.

just so i can understand the principle.
thanks again.

hi Kbw,
Now i see what was done wrong,i have actually typecasted the virtualaloc to be int,which actually returns void.

so i used it as a void:
VirtualAlloc(NULL,40*1024*1024 ,MEM_RESERVE,PAGE_READWRITE);;
VirtualAlloc(NULL,10*1024*1024 ,MEM_COMMIT ,PAGE_READWRITE);;

that means that i have a block of 10 megs commited memory.

now i need to populate this block with a string for example "test"

am trying to look how do i correlate the commited block with how do i write to there?
like in strcpy what should be the source and destination ?
thanks for all the help appriciate it a lot.


Did you not go thru the example MSDN I posted? It's all there. Just step thru the code in a debugger. If you still don't understand what it does, then please ask, but don't do so until you've debugged the example.

virtualaloc ... actually returns void
Wrong. VirtualAlloc is an allocator, it returns a raw pointer, LPVOID (a void*).
hi kbw,
ive looked at the demo -i see that it allocates 4096 pages:
from the demo:
This computer has page size 4096.
Exception is a page fault.
Allocating another page.
Exception is a page fault.
Allocating another page.

i still dont understand the main thing.
i did allocate 10 megs of memory (perfmon shows it).
now how to write repeated strings to this buffer is the missing part.
cant you show me an example ?
thanks
As I said before, VirtualAlloc allocates whole pages. So the first thing that demo does is determine the page size. There's nothing wrong with assuming it's 4K.

The app then reserves a huge block with:
1
2
3
4
5
6
7
8
    // Reserve pages in the virtual address space of the process.
    lpvBase = VirtualAlloc(
                     NULL,                 // System selects address
                     PAGELIMIT*dwPageSize, // Size of allocation
                     MEM_RESERVE,          // Allocate reserved pages
                     PAGE_NOACCESS);       // Protection = no access
    if (lpvBase == NULL )
        ErrorExit(TEXT("VirtualAlloc reserve failed."));

It then writes into the block of memory. Writing into an uncommitted page generates a page fault by the OS. There's a handler for this fault that commits the page with:
1
2
3
4
5
6
    // Otherwise, commit another page.
    lpvResult = VirtualAlloc(
                     (LPVOID) lpNxtPage, // Next page to commit
                     dwPageSize,         // Page size, in bytes
                     MEM_COMMIT,         // Allocate a committed page
                     PAGE_READWRITE);    // Read/write access 

Got it?

So to summarise, you can reserve a large block of memory. You specify null as the base address and you get an address back. To commit a page, you calculate the offset from the reserve address.

I knocked up this example, I've not compiled it so may have syntax errors:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    DWORD dwPageSize = 4*1024;
    DWORD dwNBlocks = 100;
    if (LPVOID lpvBase = VirtualAlloc(NULL, dwNBlocks*dwPageSize, MEM_RESERVE, PAGE_NOACCESS))
    {
        // Commit each page individually
        for (DWORD i = 0; i < dwNBlocks*dwPageSize; i += dwPageSize)
        {
            // we need a char* to pointer arithmetic with
            char* p = reinterpret_cast<char*>(lpvBase);

            // reserve the ith page
            VirtualAlloc(p + i, dwPageSize, MEM_COMMIT, PAGE_READWRITE);
        }

        // We're done, release the memory
        VirtualFree(lpvBase, 0, MEM_RELEASE);
    }
Last edited on
If all you want to do is allocate memory for a string what's wrong with operator new] or C function malloc ?
VirtualAlloc is raw memory allocator in windows, do you really need it's complexity ?

Read this first:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
ok thanks kbw for the explantion ,it seems like a lot of work for a simple program.
i want to resereve 40 megs and commit 10 megs not from the heap .
after that just want to fill the commited memory with repeated strings.

can you show me a full example.

from kbw i did understand the memory allocation.

this is what i have so far i know i got problem here and am still trying to understand the concept:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LPVOID lpvbase;
	LPVOID lplocate;
int i =0;
  lpvbase= VirtualAlloc(NULL,40*1024*1024 ,MEM_RESERVE,PAGE_READWRITE);; the memory
  lplocate= VirtualAlloc(NULL,10*1024*1024 ,MEM_COMMIT ,PAGE_READWRITE);; 	
  char* pszlineBuffer = (char*) lplocate; //Typecasting to char (1 Byte)
	
	
 while (i<10485760)
 {
 strcpy(pszlineBuffer,"string");

 i++;
 }
 


now trying with kbw example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

int _tmain(int argc, _TCHAR* argv[])
{
	DWORD dwPageSize = 4*1024;
    DWORD dwNBlocks = 7680;
    if (LPVOID lpvBase = VirtualAlloc(NULL, dwNBlocks*dwPageSize, MEM_RESERVE, PAGE_NOACCESS))
    {
        // Commit each page individually
        for (DWORD i = 0; i < dwNBlocks*dwPageSize; i += dwPageSize)
        {
            // we need a char* to pointer arithmetic with
            char* p = reinterpret_cast<char*>(lpvBase);
			strcpy(p,"test");
			cout << p;

            // reserve the ith page
            VirtualAlloc(p + i, dwPageSize, MEM_COMMIT, PAGE_READWRITE);
        }

        //// We're done, release the memory
        //VirtualFree(lpvBase, 0, MEM_RELEASE);

    }
	system("pause");

	return 0;
}


still dont get were do i see the reserve and how i can put repeated strings in there?

appriciate if i can see a full code for this.
regarding the new operand -this will allocate from the heap as far as i know.

thanks a lot for the help.




it seems like a lot of work for a simple program.
That's right. Perhaps you should explain what you're doing before going any further. It's not all together clear why you're pursuing this.

Can you explain what you think Reserve and Commit mean?
Last edited on
it is just for training purposes;

Reserve - is what we are reserving -this area is reserved.
commited - is the actual memory that is commited for my application.

the purpose is as follow:
1. showing how to reserve and commit memory
2. how to allocate the commited memory with repeated strings.
3. do the same thing but from the heap .

thx
it is just for training purposes;
OK, that's fine. You have a working example. But you should be aware that you wouldn't normally handle memory in this way. You might use this is a Windows specific memory allocator library ... I honestly can't think of an occasion to use this.

Reserve is a deferred allocation. The acquisition process that the OS goes thru is deferred.
Committed is the completed allocation. Your memory isn't really available until the allocation is committed.

1. showing how to reserve and commit memory
That's fine, we've done that.
2. how to allocate the committed memory with repeated strings.
I dunno about this repeated string business. If the memory allocation is completed (committed) you can copy whatever you like into it.
3. do the same thing but from the heap.
This reserve business is a feature of the Windows system allocator. It's not a general concept applicable to all heaps. In the end, they just provide you with a block of memory.
I just want to thank you -for the great help.
i appriciate it and i learn a lot from you.
Topic archived. No new replies allowed.