地图用字符串坏了?

时间:2010-12-27 13:13:03

标签: c++ debugging lua segmentation-fault

是。我看不出我做错了什么。

地图是:string,int

这是方法

bange::function::Add(lua_State *vm){  
 //userdata, function  
 if (!lua_isfunction(vm, 2)){  
  cout << "bange: AddFunction: First argument isn't a function." << endl;  
  return false;}  
 void *pfunction = const_cast<void *>(lua_topointer(vm, 2));  
 char key[32] = {0};  
 snprintf(key, 32, "%p", pfunction);  
 cout << "Key: " << key << endl;  
 string strkey = key;  
 if (this->functions.find(strkey) != this->functions.end()){  
     luaL_unref(vm, LUA_REGISTRYINDEX, this->functions[strkey]);}  
 this->functions[strkey] = luaL_ref(vm, LUA_REGISTRYINDEX);  
 return true;  

好的,当代码执行时,它会崩溃并打印出这个输出:

Program received signal SIGSEGV, Segmentation fault.  
0x00007ffff6e6caa9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >
::compare(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const () from /usr/lib/libstdc++.so.6

说真的,我的代码出了什么问题。谢谢你的帮助。

修改1:

好的,我已经完成了解决方案但仍然失败了。我试过直接插入一个字符串,但它也给出了同样的错误。

让我们看看,该对象是从bange::scene继承的bange::function。我使用lua_newuserdata创建对象:

bange::scene *scene = static_cast<bange::scene *>(lua_newuserdata(vm, sizeof(bange::scene)));
(...)
scene = new (scene) bange::scene(width, height, nlayers, vm);

我需要这个用于Lua垃圾收集。现在可以从Lua访问bange::function::Add

static int bangefunction_Add(lua_State *vm){
    //userdata, function
    bange::function *function = reinterpret_cast<bange::function *>(lua_touserdata(vm, 1));
    cout &lt&lt "object with bange::function: " &lt&lt function << endl;
    bool added = function->bange::function::Add(vm);
    lua_pushboolean(vm, static_cast<int>(added));
    return 1;
}

用户数据bange::scene存储在Lua中。事实上,当我之前创建场景时,知道userdata场景是对象的方向是相同的。我需要reinterpret_cast,然后调用方法。指针“this”仍然是方法内的相同方向。

解决

我在bange::function构造函数中做了一个小测试,没有问题。

bange::function::function(){  
    string test("test");  
    this->functions["test"] = 2;  
}  

我终于注意到问题是

bange::function *function = reinterpret_cast<bange::function *>(lua_touserdata(vm, 1));

因为对象是bange::scene而没有bange::function(我承认,指针损坏),这似乎更像代码设计问题。所以这在某种程度上得到了解决。谢谢大家。

2 个答案:

答案 0 :(得分:1)

由于strkey是您比较的唯一字符串,因此它必须是问题的根源,并且它源自堆栈上的char []。我会先摆脱它。

std::stringstream str;
str << pfunction;
string strkey = str.str();

当然,如果你损坏this,或者真的,如果你只是随时随地破坏了堆,也会发生这个错误。

答案 1 :(得分:1)

此代码可能没有任何问题。

当您的代码尝试读取或写入未映射到您的进程的内存时,会发生分段错误。它发生的点可能与bug的位置无关。

在您的程序中的某个时刻,在分段错误之前,一些代码会对堆进行操作。这可能是

  1. 访问已删除/已释放的指针
  2. 覆盖数组的边界
  3. 将对象转换为错误的类型并使用它
  4. 这些东西都不会立即崩溃 - 它们可能会默默地破坏内存。稍后,当使用该内存时,它也可能不会崩溃(只是默默地破坏其他内存)。在某些时候你会崩溃,但这一点可能与问题完全无关。

    调试策略是让第一次崩溃崩溃。有几种方法可以做到这一点。

    1. 使用调试堆。以下是Linux上GCC的一些可能性Debug heap/STL debugging equivalent for GCC?

    2. Valgrind:http://valgrind.org/