0

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.

lurker
  • 56,987
  • 9
  • 69
  • 103
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • 1
    Somewhere your code is smashing the heap otherwise `realloc` would not be fail.i would like to Suggest you to use [valgrind](http://valgrind.org/). – Dayal rai Sep 12 '13 at 10:36
  • I have looked at Valgrind and gone through the tutorials for it but not everything in it make sense in the log. It has helped to fix other issues i've had but unfortunately not this one – Boardy Sep 12 '13 at 10:39
  • As a first response the error mentioned looks more like an address in hex than the number 200... Like in this answer http://stackoverflow.com/questions/2939091/realloc-invalid-next-size I suspect that you might be over-running the malloc data structures somehow... But, your question is good and has plenty of information. I'll make my way through it slowly. – nonsensickle Sep 12 '13 at 10:43
  • [Please don't cast the return value of `malloc()`, or any other memory-allocation function, in C](http://stackoverflow.com/a/605858/28169). – unwind Sep 12 '13 at 11:00
  • Thanks unwind, I read somewhere that you should cast, does this count only for malloc or is it the same for calloc and realloc that you shouldn't cast – Boardy Sep 12 '13 at 11:04
  • Thanks unwind, I read somewhere that you should cast, does this count only for malloc or is it the same for calloc and realloc that you shouldn't cast – Boardy Sep 12 '13 at 11:04
  • I've just updated the question, I realised I wasn't resetting the currentStructIndexValue to enusre that it always between 0 and 100 to know when to realloc. The function call is also changed as it is wrapped in an if statement to ensure that 0 is returned (i.e. success). However, this has now caused glibc to show a slightly different message, i.e. invalid size and invalid pointer – Boardy Sep 12 '13 at 11:13

2 Answers2

1

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));
cbranch
  • 4,709
  • 2
  • 27
  • 25
  • Thanks this does seem to kind of work now. At least not getting the realloc errors. Its however crashing somewhere else in the code but I don't related to my original question as it seems to be somehow storing part SQL queries in part of the structure and then accessing memory out of bounds. Thanks for your help though – Boardy Sep 12 '13 at 13:34
0
        callLogSearchData = (callLogSearchDataStruct*) realloc(callLogSearchData, newSize * sizeof (callLogSearchDataStruct));
        callLogSearch = (callLogSearchResultStruct*) realloc(callLogSearch, newSize * sizeof (callLogSearchResultStruct));
        switches = (switchIDStructure*) realloc(switches, newSize * sizeof (switchIDStructure));

Left hand side of the above assignments are double pointers to which you are trying to assign a single pointer. You also use the double pointer to access the contents of the struct.

Vivek S
  • 1,251
  • 10
  • 12