Search code examples
cmemorycalloc

Calloc allocation is inconsistent


I'm creating a 2d array of integers using pointers and the calloc function. The thing is that I allocate a 3x5 matrix. And indeed, there are 3 rows but 6 columns. I can't understand this behavior. Does someone know what I'm doing wrong?

int main() {


int **new_lib = (int **) calloc(3, sizeof(int *));

if (new_lib == NULL) {
    fprintf(stderr, "Error: out of memory (create_library() part 1)\n");
    exit(1);
}

for (int i = 0; i < 3; ++i) {
    new_lib[i] = (int *) calloc(5, sizeof(int));

    if (new_lib[i] == NULL) {

        fprintf(stderr, "Error: out of memory (create_library() part 2)\n");
        exit(1);
    }
}

for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 6; ++j) {
        new_lib[i][j] = j * (i + 1) + i * (j + 1);
    }

}

for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 6; ++j) {
        printf("[%i][%i] = %i ", i, j, new_lib[i][j]);
    }
    printf("\n");
}
}

And the print is correct for one more column:
[0][0] = 0 [0][1] = 1 [0][2] = 2 [0][3] = 3 [0][4] = 4 [0][5] = 5 [1][0] = 1 [1][1] = 4 [1][2] = 7 [1][3] = 10 [1][4] = 13 [1][5] = 16 [2][0] = 2 [2][1] = 7 [2][2] = 12 [2][3] = 17 [2][4] = 22 [2][5] = 27


Solution

  • It is always consistent. Here you have some more generic. There is no allocation error checks for better code readability.

    void *allocate(size_t selem, size_t rows, size_t cols)
    {
        void **array = calloc(rows, sizeof(void *));
        
        for(size_t row =0; row < rows; row++)
        {
            array[row] = calloc(cols, selem);
        }
        return array;
    }
    
    
    int main()
    {
        int **array = allocate(sizeof(int), 3, 5);
        
        for(size_t r = 0; r < 3; r++)
        {
            printf("%p\n",array[r]);   
        }
    
        for(size_t r = 0; r < 3; r++)
        {
            for(size_t c = 0; c < 5; c++)
            {
                array[r][c] = r*10 + c;   
            }
        }
        for(size_t r = 0; r < 3; r++)
        {
            for(size_t c = 0; c < 5; c++)
            {
                printf("%02d ", array[r][c]);   
            }
            printf("\n");
        }
    }
    

    https://onlinegdb.com/Hko5Wjy5V

    edit

    You can use other types. Just pass the correct size and assign the correct pointer type

    typedef struct
    {
        double  x[1000];
        int y[500]
        /* more stuff */
    }MYSTRUCT;
    
    int main()
    {
        MYSTRUCT *ptr = allocate(sizeof(MYSTRUCT), 10, 50);