Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allocating more memory than there exists using malloc

This code snippet will allocate 2Gb every time it reads the letter 'u' from stdin, and will initialize all the allocated chars once it reads 'a'.

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#define bytes 2147483648
using namespace std;
int main()
{
    char input [1];
    vector<char *> activate;
    while(input[0] != 'q')
    {
        gets (input);
        if(input[0] == 'u')
        {
            char *m = (char*)malloc(bytes);
            if(m == NULL) cout << "cant allocate mem" << endl;
            else cout << "ok" << endl;
            activate.push_back(m);
        }
        else if(input[0] == 'a')
        {
            for(int x = 0; x < activate.size(); x++)
            {
                char *m;
                m = activate[x];
                for(unsigned x = 0; x < bytes; x++)
                {
                    m[x] = 'a';
                }
            }
        }
    }
    return 0;
}

I am running this code on a linux virtual machine that has 3Gb of ram. While monitoring the system resource usage using the htop tool, I have realized that the malloc operation is not reflected on the resources.

For example when I input 'u' only once(i.e. allocate 2GB of heap memory), I don't see the memory usage increasing by 2GB in htop. It is only when I input 'a'(i.e. initialize), I see the memory usage increasing.

As a consequence, I am able to "malloc" more heap memory than there exists. For example, I can malloc 6GB(which is more than my ram and swap memory) and malloc would allow it(i.e. NULL is not returned by malloc). But when I try to initialize the allocated memory, I can see the memory and swap memory filling up till the process is killed.

-My questions:

1.Is this a kernel bug?

2.Can someone explain to me why this behavior is allowed?

like image 479
Mike G Avatar asked Nov 03 '13 07:11

Mike G


People also ask

How do I allocate more memory to malloc?

Syntax: ptr = (cast-type*) malloc(byte-size) For Example: ptr = (int*) malloc(100 * sizeof(int)); Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory.

Does malloc allocate extra memory?

Because malloc() pads out the memory allocated to multiples of 8 bytes. Thus malloc(4) and malloc(8) allocate 8 bytes for the user, plus an extra 8 bytes for bookkeeping. Malloc(12) and malloc(16) allocate 16 bytes for the user, plus an extra 8 bytes for bookkeeping for a total of 24 bytes.

What is the maximum memory that I can allocate using malloc?

What is the maximum memory that can be allocated using malloc()? In order to represent the size internally, malloc() uses 32-bit signed integers. Because of this, in a single allocation, malloc() cannot be used to allocate more than 2 GB of memory.

What does malloc return if memory is not sufficient?

Malloc returns a null when heap memory is insufficient OR when heap is super fragmented.

What is “malloc” and “alloc”?

Let’s look at each of them in greater detail. The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large block of memory with the specified size. It returns a pointer of type void which can be cast into a pointer of any form.

Why do I only get 1 byte from malloc?

If you had written to more than 1 byte using the address given from the first malloc, you will get into troubles when you use the address from the second malloc because you will overwrite the data. So the point is you definitely get 1 byte from malloc but it might be that malloc internally has more memory allocated to you process.

What is the difference between malloc and free in C++?

The memory allocated using functions malloc() and calloc() is not de-allocated on their own. Hence the free() method is used, whenever the dynamic memory allocation takes place. It helps to reduce wastage of memory by freeing it. Syntax: free(ptr); Example:

What happens when malloc is out of memory?

If malloc is internally out of memory, it will ask the operating system some more. It will typically receive a page. Say it's 4KB in size with addresses starting at 0x1000


1 Answers

It is called memory overcommit. You can disable it by running as root:

 echo 2 > /proc/sys/vm/overcommit_memory

and it is not a kernel feature that I like (so I always disable it). See malloc(3) and mmap(2) and proc(5)

NB: echo 0 instead of echo 2 often -but not always- works also. Read the docs (in particular proc man page that I just linked to).

like image 86
Basile Starynkevitch Avatar answered Oct 27 '22 03:10

Basile Starynkevitch