1

I'm trying to dynamically allocate memory for an array of struct pointer in function. It works until 3 iteration but crash after with this error :

double free or corruption (fasttop): ...

Here is my struct pointer array declaration :

Intersection** alreadyUse = malloc(sizeof(Intersection*));

if(alreadyUse == NULL) {
   exit(1);
}

int size = 1;
alreadyUse[0] = inter; // Pointer of an Intersection

// Some Code

checkFunction(alreadyUse, &size, interLeft);

And this is my function

bool checkFunction(Intersection** alreadyUse, int* size, Intersection* inter) {

    for(int i = 0; i < *size; i++) {
        if(alreadyUse[i] == inter) {
            return true;
        }
    }

    *size = *size +1;
    Intersection** tmp = realloc(alreadyUse, sizeof(Intersection*) * *size);

    if(tmp == NULL){
        exit(1);
    }
    else {
        alreadyUse = tmp;
    }

    alreadyUse[*size-1] = inter;

    return false;
}

As I said, it works for 1, 2, 3 then I get the error.

Is someone have an idea why it works and then suddenly crash ?

Thanks for helping.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Jhiertz
  • 90
  • 6

2 Answers2

4

You change the value of alreadyUse inside checkFunction. But this has no effect on the caller. If the call to realloc actually reallocates, the caller still has a pointer to the old block that has now been freed.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

In this function call

checkFunction(alreadyUse, &size, interLeft);

the variable size is passed by reference. So it can be changed in the function. However as you see the variable alreadyUse is not passed by reference. So the function deals with a copy of the value of the variable. If you want that the variable would be changed in the function you have to pass it by reference

checkFunction( &alreadyUse, &size, interLeft);
               ^^^^^^^^^^^

Thus the function should be declared like

bool checkFunction(Intersection*** alreadyUse, int* size, Intersection* inter);
                   ^^^^^^^^^^^^^^^

The function definition can look like

bool checkFunction( Intersection ***alreadyUse, int *size, Intersection *inter ) 
{
    for ( int i = 0; i < *size; i++ ) 
    {
        if ( alreadyUse[0][i] == inter ) return true;
    }

    Intersection **tmp = realloc( alreadyUse[0], sizeof( Intersection * ) * ( *size + 1 ) );

    if ( tmp == NULL ) exit( 1 );

    alreadyUse[0] = tmp;

    alreadyUse[0][( *size )++] = inter;

    return false;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Saying `size` is passed "by reference" is confusing and inaccurate since C is a purely pass by value language. A pointer to `size` is passed by value. – David Schwartz Feb 13 '17 at 19:09
  • 1
    @DavidSchwartz The term by reference is valid and accurate in C For example "A pointer type describes an object whose value provides a reference to an entity of the referenced type". – Vlad from Moscow Feb 13 '17 at 19:16
  • Perhaps: "... a _reference_ to `size` is passed ..." – chux - Reinstate Monica Feb 13 '17 at 19:32
  • @VladfromMoscow Thank you ! It works. I thought the pointers were passed by reference, but obviously I was wrong. – Jhiertz Feb 13 '17 at 19:45
  • @David Schwartz: "Passing by reference" is a well-established language-independent concept. Its meaning is well-understood in the context of C language and it is widely used in that context. Everybody knowns that "passing something by reference" (or, sometimes "passing something by pointer") is just another (shorter) way of saying "passing a pointer to something by value". – AnT stands with Russia Feb 13 '17 at 19:58
  • @Michael Dorgan I can reverse an integer array and even know the C++ Standard algorithm std::reverse.:) – Vlad from Moscow Feb 13 '17 at 20:01
  • @VladfromMoscow Your purported example doesn't use the phrase "by reference" or "pass by reference", so it doesn't show that the phrase "by reference" is valid or accurate. And, I would add, this conflicts with the most upvoted answer defining what [pass by reference](http://stackoverflow.com/a/430958/721269) means which also explains how I learned the term, have always used the term, and have always heard the term used. – David Schwartz Feb 13 '17 at 20:23
  • @DavidSchwartz The answer in the given reference is just incorrect. The answerer does not know C.:) For example this phrase "When a parameter is passed by reference, the caller and the callee use the same variable for the parameter" does not make sense. For example parameters are not passed to functions.:) And parameters are local variables of functions. Thus the caller and the callee do not use the same variable.:) – Vlad from Moscow Feb 13 '17 at 20:26