[ODE] Re: ALLOCA

Olivier Michel Olivier.Michel at cyberbotics.com
Fri Mar 5 08:53:11 MST 2004


jon klein wrote:

> I use realloc under Windows without any problems (using MinGW) -- 
> maybe the implementation of realloc you're using is faulty.

No, this is the normal behavior of realloc. The returned pointer may be 
different from the one passed as the first argument.

> Allocating a static initial memory chunk doesn't avoid the problems in 
> existing alloca solution, since it can run out.

Sure.

> And since the stack size can be changed at compile time, I think the 
> alloca solution accomplishes the same thing.

How do you do this with gcc under Linux and under Windows ?

> Even if the stock realloc isn't working, it should be possible to do 
> roughly the same thing manually:
>
>    if (top > block_size) {
>     int new_block_size;
>     char *new_block;
>
>      new_block_size = block_size + STACK_MEMORY_CHUNK_SIZE;
>
>     new_block = malloc(new_block_size);
>     bcopy(block, new_block, block_size);
>
>     free(block);
>
>     block = new_block;
>     block_size = new_block_size;
>    }
>
> Thoughts?


This function has the same problem as realloc: when you do the 
free(block), all the pointers to this block (or inside this block) you 
previously returned become crasy pointers and you app crashes. To avoid 
this we should handle pointers to pointers (rather than simple pointers) 
and update them when a new realloc is performed which is pretty complex...

Jon Watte wrote:

>I was going to suggest something like that, although I'd prefer to keep the
>declaration outside of the macro (just for stylistic reasons). Glad you got
>it working.
>  
>
Yes, but in any case you need to pass the data type in order to be able 
to perform the cast. So the macro should be:

#define ALLOCA(t,v,s) StackMemory alloca_ ## v ( s ); v = (t*)alloca_ ## v .ptr_
[...]
  dReal *tmprow;
  ALLOCA (dReal,tmprow,n * sizeof(dReal));

And I found the declaration to be redondant (you have to say dReal 
twice), this is why I changed it to:

#define ALLOCA(t,v,s) StackMemory alloca_ ## v ( s ); t* v = (t*)alloca_ ## v .ptr_
[...]
  ALLOCA (dReal,tmprow,n * sizeof(dReal));

which is more compact and less redondant, but I guess that's just a 
matter of style taste. What do you C++ experts think about it ?

Jon Watte wrote:

>You could easily make the smart pointer revert to individual malloc()-s when the 
>initial big chunk runs out.
>  
>
Of course, but you loose the most of the interest of using a replacement 
for malloc since when your simulation needs a lot of memory space, it 
will turn out to be slow (ok, this is better than a simple crash, but at 
least we should display some warning saying that the bigChunkSize should 
be increased for a better performance)....

>Something like:
>
>class SmartPtr {
>
>public:
>
>  SmartPtr( size_t size ) {
>    if( bigChunkTop+size > bigChunk+bigChunkSize ) {
>      ptr_ = malloc( size );
>    }
>    else {
>      ptr_ = bigChunkTop;
>      bigChunkTop += size;
>    }
>  ~SmartPtr() {
>    if( ptr_ >= bigChunk && ptr_ < bigChunkTop ) {
>      bigChunkTop_ = ptr_;
>    }
>    else if( ptr_ < bigChunk || ptr_ > bigChunk+bigChunkSize ) {
>      free( ptr_ );
>    }
>  }
>
>  static void initialize( size_t size ) {
>    assert( !bigChunk );
>    bigChunk = malloc( size );
>    bigChunkTop = bigChunk;
>    bigChunkSize = size;
>  }
>
>private:
>
>  char * ptr_;
>
>  static char * bigCunnk;
>  static char * bigChunkTop;
>  static size_t bigChunkSize;
>};
>  
>


More information about the ODE mailing list