C&Lua防止访问不良或双重免费

McB*_*Bob 3 c c++ lua

我成功地将Lua集成到了我的应用程序中,为用户提供了脚本访问权限.现在我的问题是:我如何防止双重免费或不良访问违规?

我已经为每个结构实现了Init和Free函数,例如:

  • structaInit
  • structaFree

每次将struct指针链接到另一个时,我也会跟踪,增加我所有结构中的引用计数.

但是用户总是可以在Lua中做这样的事情:

a = structaInit();

b = structbInit();

structbSetA( b, a ); -- This add ++a.reference

a.reference = 0; 

a = structaFree( a ); -- If a->reference == 0 then I free

-- Then struct b->a is still a valid pointer but that have been free.
Run Code Online (Sandbox Code Playgroud)

无论如何我可以阻止这种情况发生吗?

Nic*_*las 10

问题与所有权有关.我们来看看你的Lua脚本:

a = structaInit();
b = structbInit();
Run Code Online (Sandbox Code Playgroud)

这会创建Lua现在拥有的 C对象.Lua将决定何时为这些对象释放内存.

那么这个怎么样?

structbSetA( b, a ); -- This add ++a.reference
Run Code Online (Sandbox Code Playgroud)

首先,structbSetA应该是一个成员b,通过metatable(所以它成为b:setA(a)).但更重要的是,谁拥有a

Lua.因为它必须拥有A; Lua无法完全放弃仍在Lua内存中的对象的所有权.这意味着您的内部引用计数最终毫无意义; 唯一重要的是Lua's.

如果要存储的值a之内b,这样b可以参考a,只要b还活着,那么你就需要通过建立这种关系的Lua方法.你不能只是贴在C指针,指向ab和期望一切顺利.

最简单的方法是,对于您创建的每个对象,在Lua注册表中创建一个表,该表存储Lua对象以用于它具有的任何引用.当一个对象被销毁时,你进入Lua注册表并从中删除该表,从而导致任何引用的Lua对象的销毁.显然,在以后的调用修改它时,您需要更改此值structbSetA.


另外,你为什么要把它暴露给Lua:

a.reference = 0;
Run Code Online (Sandbox Code Playgroud)

这是一个糟糕的API.Lua代码永远不必处理引用计数.你也不应该向Lua公开一个明确的"免费"方法,除非你需要Lua在完成使用后立即释放一些资源.这应该适用于操作系统类型的资源,如FILE句柄等.对于常规对象,让垃圾收集器完成它的工作.

不要将C-isms暴露给Lua代码.让Lua代码看起来像Lua代码.