Re: realloc failed to shrink memory
On 31 Aug, 01:55, FangQ <fan...@gmail.com> wrote:
hi
I got really puzzled with realloc. I am working on a function looks
like below:
void TRaytracer::Run(){
int allcount=0, uniqpt;
for(int i=0;i<domain->img->slices[0]->dim.x;i++)
for(int j=0;j<domain->img->slices[0]->dim.y;j++){
maxlen=domain->vol->getmaxdim();
L[id][i][j]=(float *)malloc(sizeof(float)*maxlen);
I[id][i][j]=(int *)malloc(sizeof(int)*maxlen);
... // do some calculations, fill the two
pointers, the count is in "uniqpt"
L[id][i][j]=(float *)realloc(L[id][i][j],sizeof(float)*(uniqpt+1));
I[id][i][j]=(int *)realloc(I[id][i][j],sizeof(int)*(uniqpt+1));
allcount+=(uniqpt+1);
}
}
It is really strange that realloc did not do any good: the memory
predicted by allcount (8*allcount bytes) is only 1/3 of the actual
increase in memory allocation! The actual allocation is 1/4 smaller
than the total amount if no realloc is uesd (i.e. malloc by maxlen).
The memory allocation is observed by "ps aux" output on a Linux box.
I know people can use std::vector to do dynamic array, but I feel
really bad that I can not understand the behavior of realloc.
Can anyone give me some hint on this
Firstly not even free() returns system memory in most
implementations.
It is actually quite hard to do this in general and always time
consuming (The blocks allocated from the system are NOT the blocks
returned by malloc)
Secondly realloc will never reallocate to a smaller size.
The reason is simple - more people care about time efficiency than
space efficiency (just browse this news group to see), realloc can't
be efficient in both time and space for size reductions and you can
always do it yourself.
Also, in a robust implementation, you must always allow for maxlen not
being enough and having to resize your arrays bigger. This is much
easier to do with std::vector.
If you write your own function to free up space with malloc()/memcpy()/
free() this is essentially what you get with the std::vector
minimization idiom:
template <typename T>
void shrinkwrap(std::vector<T>& vec, size_t epsilon = 0)
{
if( vec.size()+epsilon < vec.capacity() )
{
std::vector<T> tmp(vec); // make copy according to vec.size()
rather than vec.capacity()
vec.swap(tmp); // efficiently swap the guts of the two
// free the original (now held by tmp).
}
}
Couple this with vector::reserve and &vec[0] and there is really no
good reason not to use vector except for some communication with C.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]