2010-08-26 18 views
5

Supongamos la siguiente situación:Lua: la recolección de basura + datos de usuario

typedef struct rgb_t {float r,g,b} rbg_t; 

// a function for allocating the rgb struct 
rgb_t* rgb(r,g,b) { 
rgb_t* c = malloc(sizeof(rgb_t)); 
c->r=r; 
c->g=g; 
c->b=b; 
return c; 
} 

// expose rgb creation to lua 
int L_rgb (lua_State* L) { 
rgb_t** ud = (rgb_t **) lua_newuserdata(L, sizeof(rgb_t *)); 
*ud = rgb(lua_tonumber(L,1),lua_tonumber(L,2),lua_tonumber(L,3)); 
return 1; 
} 

Cuando la función se llama desde L_rgb Lua suceda dos asignaciones. Lua asigna nuevos datos de usuario y la función del constructor rgb asigna para la estructura. ¿Qué sucede con la variable userdata cuando la variable queda fuera de alcance en Lua? Si es basura, ¿qué ocurre con la asignación de la estructura?

Respuesta

12

Tiene dos enfoques para esta situación, y ambos podrían aplicarse a su caso específico. Otros casos te impulsan más a elegir uno sobre el otro.

  1. Puede hacerlo como lo hace en su muestra, y el uso de malloc() para obtener su bloque de datos privados, y almacenar un puntero a ella en un userdata completo. Si hace esto, debe establecer una metatabla en los datos de usuario y usar su meta-método __gc para liberar el bloque asignado cuando los datos de usuario se recogen como basura.

  2. Puede usar los datos de usuario como la asignación para su bloque de datos privado, llamando al lua_newuserdata() en lugar de malloc(). En este caso, no necesita tener un meta-método __gc porque Lua administrará directamente la vida de la asignación. Es posible que desee tener una metatabla para poder usar su entrada __index para crear la apariencia de los miembros llamados r, g y b que recuperan sus valores de su estructura.

De cualquier forma, debe pensar en el manejo de errores.

+2

El Método n.º 2 lo liberará de las asignaciones de seguimiento: en los errores de Lua y en los rebobinados de pila, el GC de Lua seguirá rastreando y liberando los bloques de códigos según corresponda. – u0b34a0f6ae

+0

¿Hay algún cambio que pueda ayudar aquí: http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname

2

agrega una metatabla a tus datos de usuario y configura la clave __gc en tu función de desasignación. Consulte the docs

+0

Alguna idea de cuál es el problema aquí: http://stackoverflow.com/questions/41080633/can-i-load-additional-functions-in-base-open-without-breaking-lua-state? – displayname

Cuestiones relacionadas