Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Allocate memory from a new virtual page in C?

I am analyzing the effect of allocation across virtual pages while creating a 2-D array of dimension PageSize x PageSize. My machine's page size is 4096. I have an array of 4096 integer pointers(columns), pointing to 4096 integers(rows).

I want to begin the allocation for the first integer pointer at a new virtual page. How can I identify if the current memory location is a new page or not? Once, I have identified that, I believe I can write some garbage values and move the pointer to a new virtual page. This is how I allocate the array.

    array = malloc(ncolumns * sizeof(int *));
    for(j = 0; j < ncolumns; j++)
    {
        array[j] = malloc(nrows * sizeof(int));
        if(array[j] == NULL)
        { reportError(8);}
    }
like image 651
user1736947 Avatar asked Sep 26 '13 02:09

user1736947


People also ask

Does malloc allocate virtual memory?

malloc() allocates the virtual memory, owned by the process. During execution the process can be reloaded to the physical memory several times by the operating system. The operating system maps virtual addresses of each process to the physical memory. A process doesn't know the mapping.

How can we change the size of allocated memory in C?

In the C Programming Language, the realloc function is used to resize a block of memory that was previously allocated. The realloc function allocates a block of memory (which be can make it larger or smaller in size than the original) and copies the contents of the old block to the new block of memory, if necessary.


2 Answers

If you know your page size, you can allocate a sufficiently sized portion of memory that will guarantee that some portion of the newly allocated memory is aligned on a page boundary. You will need to allocate at least 8192 bytes of memory to guarantee that you will have 4096 bytes aligned on a 4096 byte boundary.

For example, if you call malloc and it returns to you an offset aligned to 0xDEAD1001 (4097), you will need to go to the next page at memory address 0xDEAD2000 to get to a 4096 byte alignment. Then, you'll need at least 4096 bytes of contiguous space. Hence, the need to allocate 8192 bytes.

To get a 4k byte aligned memory location, you can add 4095 to the address returned by malloc and mask the last 3 bytes.

void *mem = malloc(8192);
void *ptr = ((void *)mem+0x0FFF) & ~ (void *)0x0FFF;

Edit: Make sure to keep a pointer to the original memory allocated, so you can later turn around and use it to call free().

Suppose this time, malloc returned 0xDEAD000F.

0xDEAD000F + 0x0000FFF = 0xDEAD100E 
0xDEAD100E & ~0x0000FFF = 0xDEAD1000

If you don't want to do all this messy pointer arithmetic, I think you could just use posix_memalign. Check it out here. If you are on a different platform, I'm sure there are similar memory alignment services available.

like image 99
Freddie Avatar answered Sep 28 '22 00:09

Freddie


Using just the features of the C language you cannot align your allocations (i.e. something that was returned from malloc) on the page boundary. Your sample code is just allocating array of pointers to arrays. Their location can be anywhere in the virtual address space. Exact location depends on the compiler/library/OS/etc.

Operating sytems typically have functions that allow doing such things. On Windows you can use VirtualAlloc function.

like image 39
Kirill Kobelev Avatar answered Sep 27 '22 23:09

Kirill Kobelev