Julia Rundström
Julia Rundström

Reputation: 35

malloc() not allocate memory for large blocks of memory

I am trying to make a program that allocates memory and then fill the allocated memory with random data, in this case A and does this a number of times and then print the time it takes to fill 100 mb in milli seconds. The program is supposed to allocate a multiple of 100 mb each time. The program is supposed to do this up to 9000 mb. The reason I do this is to demonstrate how the OS behaves when it runs out of free memory and use swap space. However I have issues doing this.

When I run the program it behaves like it's supposed to do until I reach 2100 mb then it stop allocating memory and after a while the error handler kicks in and quit the program because malloc() returns NULL.

This is the code:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <assert.h>
#include <unistd.h>
#define KILO    1024
#define MEGA (KILO*KILO)
#define INCREMENT 100

int diffTime(struct timeval * startTime, struct timeval * endTime) {
    return ((endTime->tv_sec - startTime->tv_sec)*1000 + (endTime->tv_usec- startTime->tv_usec)/1000);
}

int createBigDatablock(long int storlek) {
    char *arr = (char*) malloc(storlek*MEGA);
    if (arr==NULL){
        printf("Error: not allocating memory");
        exit (-1);  
    }
    for(int i = 0;i<storlek*MEGA;i++){
        arr[i] = 'A';
    }
    fflush(stdin);
    getchar();
    free(arr);
    return 0;
}



int main(void) {
    long int i;
    struct timeval startT, endT;
    // struct timezone tzp;
    for(i=INCREMENT;i<=9000;i=i+INCREMENT){
        gettimeofday(&startT, NULL); //&tzp); /* hämta starttid */
        createBigDatablock(i);
        gettimeofday(&endT, NULL);//&tzp); /* hämta sluttid */
        printf("Datablock  %ld MB took %d msec\n",i, diffTime(&startT,&endT));
    }
    return 0;
}

I have tried to run this on a virtual machine with debian 8 with 4 gb memory and 570 mb swap. The memory is never completely filled and the swap space is never touched. If someone can help me figure this out I will be greatful

Upvotes: 1

Views: 1563

Answers (2)

TmvFY4
TmvFY4

Reputation: 1

I stumbled on this code and compiled it on a Fedora 34 X86_64 system. It would segfault at Datablock 2100 on the loop that writes an A to a memory location. I changed the i to long int i and my system ground to almost a halt but a watched free in another terminal showed it was filling swap. I have not fully tested it but it seems to be working. There are two i variables in this and perhaps they're considered separate.

for(int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';


for(long int i = 0;i<storlek*MEGA;i++){
    arr[i] = 'A';

Upvotes: 0

Jabberwocky
Jabberwocky

Reputation: 50775

You probably have a 32bit system where you cannot allocate more than 2 gigabytes of memory per process.

If malloc returns NULL, that means that it couldn't allocate memory.

So the behaviour of your program is normal.

Another possibility is that it simply cannot find a large enough free contiguous memory block.

The reason why the swap space is never touched may be because there is always enough free memory available because your virtual machine has 4gb of memory. If you want to use the swap space, you could try to allocate lots of smaller chunks of memory, for example 40 times 100Mb; then the overall quantity of memorty you are able to allocate may also be higher than 2100Mb.

Upvotes: 4

Related Questions