lua-users home
lua-l archive

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



On 14-Jan-07, at 8:04 PM, Mike Pall wrote:

Hi,

Reuben Thomas wrote:
    FILE **pf = lua_newuserdata(L, sizeof *pf);
    *pf = 0;
    luaL_getmetatable(L, LUA_FILEHANDLE);
    lua_setmetatable(L, -2);
    *pf = /* your FILE* here */

Why is *pf initially set to NULL?

It's probably not needed in this case, but ...

  lua_newuserdata() does *not* zero the allocated memory!

It's strongly recommended to initialize all fields eventually
used by the __gc metamethod as early as possible.

E.g. an exception might get in the way and then you'll have a bad
userdata object which causes havoc when freed. This is very hard
to debug since this can happen much later.

[ Umm, is this important fact missing in the Lua manual? Well, I
usually check the source instead of the manual anyway ... :-) ]

I think it's implied, in the sense that it never promises to
clear the allocated memory, and furthermore the default
allocation method is malloc() and not calloc().

However, in the particular case which Mark Edgar and Reuben Thomas
are discussing, the FILE* presumably already exists, in which case
an out-of-memory error in lua_newuserdata (or some sort of error
in the other calls prior to the *pf assignment) will longjmp and
possibly leak the FILE*. The safe idiom is to create the userdata
and clear it, then assign the metatable, and then acquire the
resource which will be held in the userdata. (I believe this is
well-described in PiL.)

As that is not possible in a function which seeks to attach
an existing FILE* to a Lua file object, it would probably be best
to execute the function inside a protected environment, unless
the FILE* resource is not intended to be managed by Lua.