0

I tried to extend my ful list of players.

When I use the realloc function, it save my player except the last. I mean that if I had 4 players in my array and I tried to extend my array to 7 I got a new array in size 7 and just 3 players.

This is part of the function:

void initializeListForTree(Player** players, int listSize)
{
    int formulaSize = bla bla bla.....
    players = (Player **)realloc(players, sizeof(Player *)*formulaSize);
    if (!players)
    {
        printf("memory allocation failed\n");
    }
}
Mark Segal
  • 5,427
  • 4
  • 31
  • 69
motis10
  • 2,484
  • 1
  • 22
  • 46

3 Answers3

2

More something like:

void initializeListForTree(Player*** players, int listSize)
{
int formulaSize = bla bla bla.....
void *p = realloc(*players, sizeof(Player *)*formulaSize);

  if (!p) {
      printf("memory allocation failed\n");
  }
  else {
    *players = p;
  }
}

and at the call site

Player **playerslist = NULL;   

initializeListForTree(&playerslist, 1);
 ...
initializeListForTree(&playerslist, 2);
 etc..

This, of course, only if your type is a pointer to a list of pointers.

Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
1

No, you cannot change players itself () from initializeListForTree() function. C uses pass by value for function argument passing. Any changes made to player inside initializeListForTree() function won't be reflected to the actual argument used.

If you have to get that done, you'll need to pass a pointer to players.

If you don't mind having an alternate approach, if choose to return the newly allocated pointer from initializeListForTree() and collect the same into the actual argument passed, then you'll not be needing to pass a pointer-to-pointer-to-pointer.

That said,

  • Please do not cast the return value of malloc() and family in C.
  • Please do not store the return value of realloc() directly into the targeted pointer. In case realloc() fails, it will overwrite the valid entry.
Community
  • 1
  • 1
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • So you mean i need to do something like that: player[i] = realloc(player[i],sizeof(Player *)) ??? – motis10 May 29 '15 at 14:28
  • @user1703871 I have updated my answer, you can choose whochever logic suits you. :-) – Sourav Ghosh May 29 '15 at 14:34
  • @user1703871 yes, if you want to change `player[i]`, that you can certainly do from `initializeListForTree()`. but then, why you're using `realloc()`? what is issue with a simple `malloc()`? – Sourav Ghosh May 29 '15 at 14:36
0

Where realloc() find the extend memory:

  • If there are enough free space after the original memory, then it will use that, and the original address don't change.
  • If orignal memory is at end of heap/.. , it extend the memory, so the original address don't change.
  • If original memory is in middle of heap/.., and there is not enough space, then it will allocate a new memory block, and copy your original memory into the new ones, so the address change.

The last case happens with big chance, so you always need to update your address after call realloc().

And the old address might be put into the free memory list, you should not touch it any more. It might be allocated by another malloc()/.. call in future.

And you can see that, realloc() could be heavy, because it might need to copy memory, so improve code to avoid to use it, if possible.


Here is a possible use case (from TLPI):

    // nptr is new pointer, ptr is your original pointer,

    nptr = realloc(ptr, newsize);
    if (nptr == NULL) {
        /* Handle error */
    } else {
        /* realloc() succeeded */
        ptr = nptr;
    }

Basicly, first check return value to see whether it succeed:

  • If failed, then original memory remain unchange.
  • If succeed, assign new address to original pointer.

And, you need to make sure you don't have another pointer that point to middle of original memory, because that would change too, use offset to start address could make things easier.


If your array size change frequently, then you might allocate a bigger memory, remember its size, and reallocate it only when the size is reached, when resize you also give a bigger value than the new value.

You can choose a factor when resize, e.g factor = 1.5, means: new_size = old_size * factor.

Eric
  • 22,183
  • 20
  • 145
  • 196