lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi,

[Lua 5.2.2]

While trying to reduce the memory allocations of our application  I came 
across a function that always allocates a table, sets some members, calls another
function with this table as argument.  Both the caller and the callee don't reference
the table thereafter.  I thought this would be a good candidate to always use the
same table.

But when using our custom memory allocator, I still see a lot of allocations at this 
point that I dont expect anymore.

You can see the behaviour with the following program.  I would expect that the loop 
reaches a state, where no more memory allocations are neccesary.  But like 2 times
out of 3 the following output happens:

  loop
  ptr=(nil) osize=0 nsize=0 res=(nil)
  ptr=(nil) osize=0 nsize=80 res=0x937da40
  ptr=0x937d9e8 osize=80 nsize=0 res=(nil)
  loop
  ptr=(nil) osize=0 nsize=0 res=(nil)
  ptr=(nil) osize=0 nsize=80 res=0x937d9e8
  ptr=0x937da40 osize=80 nsize=0 res=(nil)
  [repeated...]

As you can see, one loop always frees the block allocated in the previous loop, and
a new block of the same size will be allocated.  This seems unnecessary. 
I suspect that hash-collisions are somehow responsible for this behaviour.  Because it
does not happen every time.  
Is this to be expected?


   Jörg


#include <lua.h>
#include <stdlib.h>
#include <stdio.h>

void* realalloc( void* ptr, size_t osize, size_t nsize )
{
  if( nsize == 0 )
  {
    free( ptr );
    return NULL;
  }
  return realloc( ptr, nsize );
}

void* alloc( void* ud, void* ptr, size_t osize, size_t nsize )
{
  void* res = realalloc( ptr, osize, nsize );
  printf( "ptr=%p osize=%d nsize=%d res=%p\n", ptr, (int)osize, (int)nsize, res );
  return res;
}

int main()
{
  int i;
  lua_State* L = lua_newstate( alloc, 0 );
  lua_pushstring( L, "xyz" );
  lua_pushstring( L, "valid" );
  lua_pushstring( L, "value" );
  lua_pushstring( L, "linepos" );
  lua_pushstring( L, "linecol" );
  lua_pushstring( L, "fashion" );
  lua_newtable( L );
  for( i = 0; i < 1000; ++i )
  {
    printf( "loop\n" );
    lua_pushinteger( L, 4 );
    lua_setfield( L, -2, "valid" );
    lua_pushstring( L, "xyz" );
    lua_setfield( L, -2, "value" );
    lua_pushnil( L );
    lua_setfield( L, -2, "linepos" );
    lua_pushnil( L );
    lua_setfield( L, -2, "fashion" );
    lua_pushnil( L );
    lua_setfield( L, -2, "linecol" );
  }
}