-6

Looks like realloc doesn't free old memory (on success or failure), while vector always delete old memory and allocate a new block.

Can I say for POD data, realloc has better performance than vector?

For example:

int *p = malloc(5 * sizeof(int));
...
int *new_p = (int*) realloc(p, 10 * sizeof(int));

Will the old memory p be freed here?

Jongware
  • 22,200
  • 8
  • 54
  • 100
Deqing
  • 14,098
  • 15
  • 84
  • 131
  • 1
    This [link](http://stackoverflow.com/questions/22932984/is-it-fair-to-always-recommend-stdvector-over-realloc) may help. – vITs May 29 '14 at 09:49
  • 3
    You are mistaken about realloc() not freeing the old memory. – user207421 May 29 '14 at 09:50
  • Ok, looks like I don't understand how `realloc` works, and someone shed some lights? thanks. – Deqing May 29 '14 at 10:16
  • Some light on what? What's the question? – user207421 May 29 '14 at 10:44
  • @Deqing: `realloc` will attempt to resize the existing area. If this doesn't work it will attempt to allocate a new area, copy the old data then free the old area. If this also doesn't work then it returns `NULL` (it fails), but does so in a way that doesn't destroy the original data (allowing the caller to do sane recovery and possibly work around the problem). – Brendan May 29 '14 at 10:48

2 Answers2

1

Realloc may expand the actual allocation (if possible) or may allocate a new chunk, copy the old chunk values and free the old chunk. In the first case it has better performance, but, as you don't know in advance what it's going to do, you must suppose that pointers to the old chunk will become invalid.

Mabus
  • 1,418
  • 12
  • 20
  • Your initial statement is false; if it were true, this: `if (new_p) free(p);` would always lead to UB. **Edit** hold on. Could I be mistaken in this? It's a fairly convential statement; but see, e.g., http://en.cppreference.com/w/c/memory/realloc – Jongware May 29 '14 at 10:32
  • 1
    I don't see your point. Even if realloc grows your allocation, it returns a pointer to the allocated area (in this case new_p == p). – Mabus May 29 '14 at 10:40
  • My bad, I remembered it the wrong way around. `realloc` already frees the original memory if needed. I must have been confusing this with the more common question "what to do if `realloc` fails?". – Jongware May 29 '14 at 11:48
  • The first case is exactly what I was asking, though I agree that the old chunk is very likely become invalid. – Deqing May 30 '14 at 01:44
1

The only significant difference (ignoring "syntactical sugar") is that realloc() may try to increase the size of the existing area; and vector can't do this and therefore always has to allocate a new area, copy the old data into the new area, then free the old area.

Based on this, there are 2 cases where realloc() would be superior. The first is when the data is large (and therefore copying all of it is expensive) and being able to increase the size of the area avoids expensive copying.

The second case is where you simply don't have enough (virtual) memory to allow 2 copies to exist at the same time. For example, if you're on a 32-bit computer with 2 GiB of space available for data and you've got a 1.5 GiB array, then you can't allocate a second 1.5 GiB array (not enough space) and must either extend the existing area or fail.

Note that for both of these scenarios (which are relatively rare), both realloc() and vectors are likely to be inferior to other approaches. For a simple example, instead of having a huge array maybe you can break it up into a linked list of "sub arrays" (e.g. a linked list of 1000 "sub-arrays" that are 1.5 MiB each instead of a single 1.5 GiB array; such that it's easy to create a new "sub-array" and add it to the end of the list). Of course there are also disadvantages to other approaches (e.g. for the "linked list of sub-arrays" example, iteration becomes slightly more complex).

Brendan
  • 35,656
  • 2
  • 39
  • 66