我可以在使用lua_pushnumber时调整堆栈的最大大小吗 [英] Can I resize the max size of the stack when using lua_pushnumber

查看:654
本文介绍了我可以在使用lua_pushnumber时调整堆栈的最大大小吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

We have a problem in our project,we use lua 5.1 as our scripting language.

但是当使用lua_pushnumber一次将太多数据从C ++传递到lua时 函数,lua堆栈看起来像堆栈溢出,并导致内存的其他部分 在C ++中已被编写,并且当回调返回时,它会导致我们的系统崩溃 到C ++.我想知道是否有一些参数可以控制尺寸 lua堆栈大小.我尝试更改lua.h中定义的参数LUA_MINSTACK, 但似乎不起作用.我也尝试使用lua_checkstack()避免推送 太多的数字无法堆叠lua,但它也无法正常工作

But when using lua_pushnumber to pass too many data from C++ to lua in one function, lua stack seems like stack-overflow and cause other part of the memory in C++ has been written, and it cause our system crash when the callback return to C++. I want to know whether there are some parameters to control the size of lua stack size. I try to change the parameter LUA_MINSTACK which defined in lua.h, but it seems doesn't work. I also try to use lua_checkstack() to avoid pushing too many number to lua stack but it also doesn't work

getNineScreenEntity(lua_State* L)
{
    DWORD screenid = GET_LUA_VALUE(DWORD,1)
    struct EntryCallback : public ScreenEntityCallBack
    {
        EntryCallback(){ }
        bool exec(ScreenEntity * entity)
        {
            list.push_back(entity)
            return true;
        }
        std::vector<ScreenEntity*> list;
    };
    EntryCallback exec;
    Screen* screen = ScreenManager::getScreenByID(screenid);
    if (!screen)
        return 0;
    screen->execAllOfScreenEntity(exec);
    int size = 0;
    std::vector<ScreenEntity*>::iterator vit = exec.list.begin();
    for (; vit != exec.list.end(); ++vit)
    {
        lua_pushnumber(L,(*vit)->id);
        ++size;    
    }
    return size;
} 

似乎在一个屏幕中有太多实体时,我们的程序将崩溃.

It seems like when there are too many entities in one screen, our program will crash.

推荐答案

也许会有所帮助(来自Lua 5.2手册)

Maybe this will help (from Lua 5.2 manual)

int lua_checkstack (lua_State *L, int extra);

确保堆栈中至少有额外的"可用堆栈插槽.如果它不能满足请求,则返回false,因为这将导致堆栈大于固定的最大大小(通常至少为几个)千个元素),或者因为它无法为新的堆栈大小分配内存.此函数永远不会缩小堆栈;如果堆栈已经大于新的大小,则将其保持不变."

"Ensures that there are at least 'extra' free stack slots in the stack. It returns false if it cannot fulfill the request, because it would cause the stack to be larger than a fixed maximum size (typically at least a few thousand elements) or because it cannot allocate memory for the new stack size. This function never shrinks the stack; if the stack is already larger than the new size, it is left unchanged."

这是一个示例c函数...

Here is an example c function...

static int l_test1 (lua_State *L) {
    int i;
    printf("test1: on the way in"); stackDump(L);
    int cnt = lua_tointeger(L, 1);
    printf("push %d items onto stack\n", cnt);
    printf("try to grow stack: %d\n", lua_checkstack(L, cnt));
    for (i=0; i<cnt; i++) {
        lua_pushinteger(L, i);                      /* loop -- push integer */          
    }
    printf("test1: on the way out"); stackDump(L);
    return 1;
}

此代码:

  • 将栈中的内容转储到函数中. (1)
  • 尝试扩展堆栈大小以具有"cnt"个空闲插槽(返回true表示有效,或者false表示无效).
  • 在堆栈上增加整数的'cnt'
  • 在出栈时转储堆栈.
$ lua demo.lua 
running stack test with 10 pushes
test1: on the way in
---1--
[1] 10
-----
push 10 items onto stack
test1: on the way out
---11--
[11] 9
[10] 8
[9] 7
[8] 6
[7] 5
[6] 4
[5] 3
[4] 2
[3] 1
[2] 0
[1] 10
-----
running stack test with 1000 pushes
test1: on the way in
---1--
[1] 1000
-----
push 1000 items onto stack
try to grow stack: 1
test1: on the way out
---1001--
[1001] 999
[1000] 998
[999] 997
[998] 996
[997] 995
[996] 994
...


当上面的代码没有调用lua_checkstack()时,尝试将1000个项目推入堆栈时会出错.


When the code above doesn't have the lua_checkstack() call, we get an error trying to push 1000 items onto the stack.

running stack test with 1000 pushes
test1: on the way in
---1--
[1] 1000
-----
push 1000 items onto stack
Segmentation fault (core dumped) 
$


(1)stackDump()与在PiL第三版中出现的类似.用于转储堆栈内容.


(1) stackDump() is similar to what appears in PiL 3rd ed. for dumping stack contents.

这篇关于我可以在使用lua_pushnumber时调整堆栈的最大大小吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆