Search code examples
cstructurerealloc

Reallocating memory causes invalid next size


I am working on a project in C, I am very new to C so this may be a very simple answer but I can't find out how I can resolve this issue.

What I have is a structure which is defined in the header file in the following way.

typedef struct CallLogSearchDataStruct
{
    char * date;
    char * time;
    char * bParty;
    char * aParty;
    float duration;
    char * cleardownCause;
    struct CallLogSearchOutboundStruct * outboundLegs;
} callLogSearchDataStruct;

It is then referenced and allocated using the following code snippet.

callLogSearchDataStruct * callLogSearchData = NULL;

callLogSearchData = (callLogSearchDataStruct*)calloc(INITIAL_CALL_STRUCT_SIZE,sizeof(callLogSearchDataStruct));

INITIAL_CALL_STRUCT_SIZE is set to be 100.

I have some code which loops round in a while loop which is incrementing a variable called currentStructIndexValue. Each time this value is incremented, I call a function called reallocateStructures. This contains various paramaters such as the structure array that I want to re-allocate.

I.e. what is supposed to happen, the callLogSearchDataStructure is calloc'd to be the size of 100. When the currentStructIndexValue value goes to 101 and the reallocateStructures function is called, the structure is supposed to resize to contain another 100, i.e. now contain 200.

Below is the code for the reallocateStructures function where I am having the problem.

int reallocateStructures(callLogSearchResultStruct **callLogSearch, callLogSearchDataStruct ** callLogSearchData, 
        switchIDStructure ** switches, int *timesStructHasBeenReallocated, int currentStructIndexValue,
        int dataRow)
{
    int INITIAL_CALL_STRUCT_SIZE = 100;
    int currentSize = 0;
    int newSize = 0;
    int initFromIndex = 0;

    if (currentStructIndexValue == INITIAL_CALL_STRUCT_SIZE) {
        printf("REALLOCATING STRUCTURES");
        currentSize = currentStructIndexValue * *timesStructHasBeenReallocated;

        newSize = currentSize + INITIAL_CALL_STRUCT_SIZE;
        *timesStructHasBeenReallocated = *timesStructHasBeenReallocated + 1;

        callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
        callLogSearch = (callLogSearchResultStruct*) realloc(callLogSearch, newSize * sizeof (callLogSearchResultStruct));
        switches = (switchIDStructure*) realloc(switches, newSize * sizeof (switchIDStructure));

        for (initFromIndex = currentSize; initFromIndex < newSize; initFromIndex++) {
            callLogSearchData[initFromIndex]->aParty = NULL;
            callLogSearchData[initFromIndex]->bParty = NULL;
            callLogSearchData[initFromIndex]->cleardownCause = NULL;
            callLogSearchData[initFromIndex]->date = NULL;
            callLogSearchData[initFromIndex]->duration = 0;
            callLogSearchData[initFromIndex]->outboundLegs = NULL;
            callLogSearchData[initFromIndex]->time = NULL;

            callLogSearch[initFromIndex]->date = NULL;
            callLogSearch[initFromIndex]->dRowIndex = dataRow;

            switches[initFromIndex]->switchID = NULL;
        }
        return 0;
    }
    return 1;
}

Below is how I am calling the above method

if (reallocateStructures(&callLogSearch, &callLogSearchData, &switches, &timesStructHasBeenReallocated, currentStructIndexValue, dataRow) == 0)
{
   //Structures have been reallocated so reset the index
   currentStructIndexValue = 0;
}

I have stepped through the code in GDB and found that the currentSize, newSize variable are correct, i.e. the current size is 100, the new size will be 200 but when it does the first realloc for the callLogSearchData my app crashes with the following GDB message

*** glibc detected *** realloc(): invalid size: 0xbfffed18 ***
*** glibc detected *** realloc(): invalid pointer: 0xbfffed1c ***
*** glibc detected *** realloc(): invalid pointer: 0xbfffed14 ***

Thanks for any help you can provide.


Solution

  • In your reallocateStructures function, you pass a pointer-to-a-pointer for each item. When you call realloc() you should deference the pointer-to-pointer to get the original pointer, both for the input parameter and when assigning the result. In other words, you currently have:

       callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
    

    You want:

       *callLogSearchData = (callLogSearchDataStruct*) realloc(*callLogSearchData, newSize * sizeof (callLogSearchDataStruct));