карта со строкой сломана? - PullRequest
1 голос
/ 27 декабря 2010

Да.Я не вижу, что я делаю неправильно.

Карта: 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.Теперь доступ к bange::function::Add из Lua:

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;
}

Userdata 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 ]

1 голос
/ 27 декабря 2010

Возможно, в этом коде нет ничего плохого.

Ошибка сегментации возникает, когда ваш код пытается прочитать или записать в память, которая не сопоставлена ​​с вашим процессом.Дело в том, что это может не относиться к тому, где ошибка.

В какой-то момент в вашей программе, до ошибки сегментации, какой-то код копировал кучу.Это может быть

  1. Доступ к удаленному / освобожденному указателю
  2. Перезапись границ массива
  3. Приведение объекта к неверному типу и его использование

Ни одна из этих вещей не должна сразу падать - они могут просто молча испортить память.В какой-то момент позже, когда эта память используется, она также может не потерпеть крах (просто молча испортить другую память).В какой-то момент происходит сбой, но этот момент может быть совершенно не связан с проблемой.

Стратегия отладки состоит в том, чтобы получить первое повреждение, которое вылетит.Есть несколько способов сделать это.

  1. Использовать кучу отладки.Вот некоторые возможности для GCC в Linux Эквивалент отладки кучи / STL для GCC?

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

1 голос
/ 27 декабря 2010

Поскольку strkey - единственная строка, которую вы когда-либо сравниваете, она должна быть источником проблем, и она исходит из char [] в стеке. Я бы начал с того, чтобы избавиться от этого.

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

Конечно, эта ошибка также может возникнуть, если вы испортили this, или действительно, если вы просто распаковали поврежденную кучу в любом месте, в любое время.

...