Search code examples
cmemorysizeallocationcalloc

calloc does not work for large numbers


In my program, calloc() does not work for more than 38 size, but with less than this number it works perfectly. In this case, I want to allocate 128 of int, and release it afterwards.

What's up?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    int *a;
    int *x;
    x = malloc(512 / sizeof(int));
    a = x;
    int n = (512 / sizeof(int));
    int i;
    for (i = 0; i < n; i++)
    {
        printf("Address of x[%d] = %x\n", i, x );
        printf("Value of x[%d] = %d\n", i, *x );
        x++;
    }
    free(a);
    int *y = (int *)malloc(512 / sizeof(int));
    a = y;
    for (i = 0; i < n; i++)
    {
        printf("Address of y[%d] = %x\n", i, y );
        printf("Value of y[%d] = %d\n", i, *y );
        y++;
        *y = i + 1;
    }
    free(a);
    int *z = (int *)calloc(38, sizeof(int));
    a = z;
    for (i = 0; i < 38; i++)
    {
        printf("Address of z[%d] = %x\n", i, z );
        printf("Value of z[%d] = %d\n", i, *z );
        z++;
    }
    free(a);
    return 0;
}

Solution

  • First problem, you don't initialize the values of x or y and still you try to print them, while the other problem, being the more important, is:

    n = 512/sizeof(int)
    

    and then you malloc

    x = malloc(512/sizeof(int))
    

    you should malloc this way

    x = malloc(n*sizeof(int))
    

    which yields

    x = malloc(512)
    

    but since you want to allocate 128 of int, it is clearer to do

    n = 128;
    x = malloc(n * sizeof(int));
    

    this is the fixed code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int *a;
        int *x;
        x = malloc (512);
        a = x;
        int n = (512/sizeof(int));
        int i;
        for (i = 0; i < n; i++)
        {
            *x = i; /* intialize the value of x[i] */
            printf("Address of x[%d] = %p\n", i, x );
            printf("Value of x[%d] = %d\n", i, *x );
            x++;
        }
        free(a);
    
        int *y = malloc(512);
        a = y;
        for (i = 0; i < n; i++)
        {
            *y = i+1; /* initialize the value of y[i] */
            printf("Address of y[%d] = %p\n", i, y );
            printf("Value of y[%d] = %d\n", i, *y );
            /* *y = i+1; move this before the printf */
            y++;
        }
        free(a);
        int *z = calloc(38, sizeof(int));
        a = z;
        for (i = 0; i < 38; i++)
        {
            printf("Address of z[%d] = %p\n", i, z );
            printf("Value of z[%d] = %d\n", i, *z );
            z++;
        }
        free(a);
        return 0;
    }
    

    You must always check the result of malloc it returns NULL on failure. If it does return NULL and you don't check, you would dereference a NULL pointer, which is not a good idea.

    The irony is that the only part of your code that was actually right, was the calloc part, except for not checking the returned value from it.