Search code examples
cmemory-managementfreeallocation

C - free function crashes


I tried checking the addresses and its all looking normal, printing works and everything else works as well. But when it tries to free the memory, the program crashes. CODE:

#include <stdio.h>
#include <stdlib.h>
#define FIRST_DIM 2
#define SECOND_DIM 3
#define THIRD_DIM 2
#define TOTAL 12
void getNums(float* pArr);
void sortArr(float* pArr);
void printArr(float* pArr);
int main(void)
{
    // Variable assignment
    unsigned int i = 0, j = 0;
    float*** pppArr = NULL;

    // Memory assignment
    pppArr = (float***)calloc(FIRST_DIM, sizeof(float**));
    if (!(pppArr))
    {
        printf("Failed Allocating Memory..\n");
        system("PAUSE");
        return 1;
    }
    for (i = 0; i < FIRST_DIM; i++)
    {
        *(pppArr + i) = (float**)calloc(SECOND_DIM, sizeof(float*));
        if (!(*(pppArr + i)))
        {
            printf("Failed Allocating Memory..\n");
            system("PAUSE");
            return 1;
        }
    }
    for (i = 0; i < FIRST_DIM; i++)
    {
        for (j = 0; j < SECOND_DIM; j++)
        {
            *(*(pppArr + i) + j) = (float*)calloc(THIRD_DIM, sizeof(float));
            if (!(*(*(pppArr + i) + j)))
            {
                printf("Failed Allocating Memory..\n");
                system("PAUSE");
                return 1;
            }
            printf("%p && %d\n", *(*(pppArr + i) + j), **(*(pppArr + i) + j));
        }
    }
    printf("ASD");
    // Getting numbers, sorting them and printing them out
    getNums(**pppArr);
    sortArr(**pppArr);
    printArr(**pppArr);

    // End of program
    // Releasing memory
    for (i = 0; i < FIRST_DIM; i++)
    {
        for (j = 0; j < SECOND_DIM; j++)
        {
            free(*(*(pppArr + i) + j));
        }
    }
    for (i = 0; i < FIRST_DIM; i++)
    {
        printf("%p\n", *(pppArr + i));
        free(*(pppArr + i));
    }
    free(pppArr);
    system("pause");
    return 0;
}

/* This function gets values for the given array from the user */
void getNums(float* pArr)
{
    unsigned int i = 0;
    for (i = 0; i < TOTAL; i++)
    {
        printf("Enter Number %d: ", i);
        scanf("%f", pArr + i);
        getchar();
    }
}

/* This function prints out the given array */
void printArr(float* pArr)
{
    unsigned int i = 0;
    for (i = 0; i < TOTAL; i++)
    {
        printf("Number %d: %.2f\n", i, *(pArr + i));
    }
}

/* This function sorts the given array from lowest to highest*/
void sortArr(float* pArr)
{
    unsigned int i = 0, j = 0;
    float temp = 0;
    for (i = 0; i < TOTAL; i++)
    {
        for (j = 0; j < TOTAL - 1; j++)
        {
            if (*(pArr + j) > *(pArr + j + 1))
            {
                temp = *(pArr + j);
                *(pArr + j) = *(pArr + j + 1);
                *(pArr + j+ 1) = temp;
            }
        }
    }
}

is there something im missing?


Solution

  • When you use pointers and dynamic allocation, the memory you allocate will most likely not be contiguous, but you will get separate memory areas for each allocation. That means when you treat it as one large contiguous memory area in your functions you exhibit undefined behavior.

    An actual array, like

    float arr[FIRST_DIM][SECOND_DIM][THIRD_DIM];
    

    Now that will be contiguous.

    See e.g. this old answer of mine for a more "graphical" explanation of the difference between arrays of arrays, and pointers to pointers.