版权声明:本文为博主原创文章,未经博主允许不得转载。
int luaL_ref (lua_State *L, int t);
Creates and returns a reference, in the table at index t, for the object at the top of the stack (and pops the object)….
You can retrieve an object referred by reference r by calling lua_rawgeti(L, t, r). Function luaL_unref frees a reference and its associated object.
在当前栈索引t处的元素是一个table, 在该table中创建一个对象, 对象是当前栈顶的元素, 并返回创建对象在表中的索引值, 之后会pop栈顶的对象; (即将栈顶元素放到t对应的table中)
freelist是值为0的宏, 所以可以任务总是将t的第0个值存放了下一个空闲位置的坐标;
空闲位置通过相互连接得到一个freelist: ref = t[freelist] 存放的是上一个之前被unref的元素的位置, 而 t[ref] 则是存放上上个unref的元素位置, 这样的连接方式就形成了freelist, 以便快速查找;LUALIB_API int luaL_ref (lua_State *L, int t) { int ref; if (lua_isnil(L, -1)) { lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* 'nil' has a unique fixed reference */ } t = lua_absindex(L, t); lua_rawgeti(L, t, freelist); /* get first free element 当前freelist保存了一个空闲元素位置 */ ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ lua_pop(L, 1); /* remove it from stack */ //下面两步就是将当前freelist指向的ref位置的元素从freelist中删除, // 同时将上上个被unref的元素位置放到freelist中; lua_rawgeti(L, t, ref); /* remove it from list t[ref] 存放的是上上个被unref的元素 */ lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ } else /* no free elements */ ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ lua_rawseti(L, t, ref); // 将栈顶元素设置到t[ref] return ref; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
下面看unref的函数源码:
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { if (ref >= 0) { t = lua_absindex(L, t); lua_rawgeti(L, t, freelist); lua_rawseti(L, t, ref); /* t[ref] = t[freelist] 类似将unref的位置插入链表头 */ lua_pushinteger(L, ref); lua_rawseti(L, t, freelist); /* t[freelist] = ref */ } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可以用一个简单的例子来演示luaL_ref的用法:
// main.lua中有个全局函数 function gf() print("hello world") end // c++中处理 void callgf() { lua_getglobal(L,"gf"); // 存放函数到注册表中并返回引用 int ref = luaL_ref(L,LUA_REGISTRYINDEX); // 从注册表中读取该函数并调用 lua_rawgeti(L,LUA_REGISTRYINDEX,ref); lua_pcall(L,0,0,0); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
上面的函数会调用gf打印出”hello world”
Lua采用了基于垃圾收集的内存管理机制,因此对于程序员来说,在很多时候内存问题都将不再困扰他们。然而任何垃圾收集器都不是万能的,在有些特殊情况下,垃圾收集器是无法准确的判断是否应该将当前对象清理。这样就极有可能导致很多垃圾对象无法被释放。为了解决这一问题,就需要Lua的开发者予以一定程度上的配合。比如,当某个table对象被存放在容器中,而容器的外部不再有任何变量引用该对象,对于这样的对象,Lua...
Lua表的引用特征、Lua表的赋值、Lua表的移除 分析,建立一张table_a表,并向其中插入‘A’、‘B’、‘C’三个字符,将table_a赋值给table_b,再向table_b插入字符’D’,紧接着向table_a插入字符’E’,把table_a表移除,打印出table_...
Lua是具备自动内存管理的我们只管创建对象,无须删除对象(当然,对于不要的对象你需要设置一下nil值),Lua会自动删除那些被认为是垃圾的对象。问题就出现在,什么对象才是垃圾对象,有些时候,我们很清楚某个对象是垃圾,但是,Lua却无法发现。 例子: 首先以一个table,叫做t。然后创建一个新的table——key1,这个key1作为t的key值,给t新增了一个字段,赋值为...
简述 一个table可以通过元表的__mode字段设置成弱引用模式,一般来说由三个模式: key是弱引用 value是弱引用 key和value都是弱引用 作用 Lua采用垃圾自动回收的内存管理机制,但有时候Lua并不能正确判断对象是否需要被销毁,导致某些需要被销毁的对象一直存在,造成内存泄漏。 如下代码Test.lua, 输出为, 程序本身的意料是,但key第二次被赋值为{}时,a...
最近被问到一个问题,什么是lua表的弱引用,之前看过lua程序设计第四版,但是当时不记得了,并不能回答出来。之后做了简单查阅,作此记录。 lua的垃圾回收机制是,当一个变量不再被引用了。当触发垃圾回收机制的时候,会回收这部分内存。而弱引用,则是更好的回收内存的一种方法。下面上代码: &nbs...
Lua 简介 Lua是脚本型语言 动态编译 动态执行 每次修改不需要重新编译链接执行 运行时编译而并非运行前编译 是C语言编写的 速度比C语言快 特性 Lua的Hello World Lua行末不要分号 Lua的括号 Lua语言几乎用不到大括号,取而代之的是do…end Lua的注释 小心不要变成纯文本了 数据类型 Lua是动态类型,不需要定义就可以直接使用 Lua的数据类型是动态可...
摘要 参考 Lua中有8个基本类型分别为:nil、boolean、number、string、userdata、function、thread和table。 方括号 "[[]]" 来表示"一块"字符串 table 类似python中的字典...
ubuntu安装lua 下载安装lua下载 在执行make时可能会报readline什么的错误 直接运行lua,可以查看是否安装成功 语法 注释 单行注释: – 多行注释: --[[ 多行注释 多行注释 –]] lua保留关键字 and break do else elseif end false for function if in local nil not or re...
Lua 特性 轻量级: 它用标准C语言编写并以源代码形式开放,编译后仅仅一百余K,可以很方便的嵌入别的程序里。 可扩展: Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。 其它特性: 支持面向过程(procedure-oriented)编程和函数式编程(functional programming); 自动内存管...
lua5.2后, 官方建议大家放弃module/package机制, 这套机制对于使用者来说是方便的, 对于module的编写者简直要抓狂, 所有module后的函数对_G均不可见, 还要一个个手动在module前转成local调用. 相当反人类. 官方建议大家手动实现package机制. 本博客之前有实现过, 参考http://www.cppblog.com/sunicdavy/archive/...