Administrator
Administrator

Reputation: 327

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?

Upvotes: 1

Views: 105

Answers (2)

Tom Karzes
Tom Karzes

Reputation: 24052

This code is indexing out of bounds rather severely. The memory allocated for pppArr has three levels of indirection. It is not a multi-dimensional array (i.e., not an array of arrays), but is a pointer to an array of pointers to arrays of pointers. Three levels of indirection. There are 6 separate float slices, each with 2 contiguous elements (i.e., THIRD_DIM).

When calling getNums, sortArr, and printArr, you are passing **pppArr. This is equivalent to passing pppArr[0][0], which points to a single 2-element sequence of float values. The functions may only access THIRD_DIM elements, i.e. 2. Instead, they are trying to access 12 elements (i.e., TOTAL), which of course corrupts memory and leads to undefined behavior.

As far as I can tell, it looks like you're trying to access the storage as a single one-dimensional array. If so, then the easiest way to fix it is to eliminate 2 levels of indirection, and get rid of FIRST_DIM, SECOND_DIM, and THIRD_DIM, and just allocate a single, flat array with LENGTH elements. The pointer would have type float *.

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409176

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.

Upvotes: 2

Related Questions