Библиотека C++ и C с использованием longjmp

Я работаю с Lua, у которого есть C API, а его функции обработки ошибок используют longjmps. При возникновении ошибки я сначала создаю сообщение, описывающее, что пошло не так, а затем говорю Lua, чтобы он вызвал ошибку. Например

std::stringstream ss;
ss << "'" << function->cb->name << "' expects at most " << maxargs_all  
<< " argument(s) and received " << nargs;
luaL_error(L, ss.str().c_str());

Насколько я понимаю, longjmp не раскрутит стек, поэтому мой объект stringstream не будет уничтожен. Если я правильно помню, stringstream и другие библиотечные классы C++ обычно размещают данные в куче, которая освобождается при уничтожении объекта. Однако здесь не будет вызываться деструктор, поэтому я думаю, что это приведет к утечке памяти. В зависимости от человека, написавшего сценарий, я потенциально мог вызвать много ошибок и, таким образом, утечь много памяти.

Я уверен, что другим людям нужно было решить подобную проблему, но я не могу найти ничего, что мне нужно. Во многих местах говорится, что объекты не будут уничтожены, но я предполагаю, что должен быть способ гарантировать освобождение памяти?


person user1520427    schedule 26.11.2012    source источник
comment
ss.str().c_str() Никогда, никогда не делайте этого для ничего, связанного с Lua или нет.   -  person Nicol Bolas    schedule 26.11.2012
comment
@NicolBolas Хм, почему это? Выходит ли string из ss.str() за пределы области действия до фактического выполнения вызова, что потенциально делает строку c недействительной?   -  person user1520427    schedule 27.11.2012
comment
Технически... нет. Но вообще это плохой тон; это указатель на временную память. Все проблемы возникают из-за такого рода вещей.   -  person Nicol Bolas    schedule 27.11.2012
comment
@NicolBolas Какие проблемы могут возникнуть, которые не могут возникнуть с локальной переменной?   -  person user1520427    schedule 27.11.2012


Ответы (1)


Решение состоит в том, чтобы скомпилировать Lua как библиотеку C++. Тогда luaL_error() вызовет исключение вместо вызова longjmp() и все будет уничтожено раскручиванием стека.

person Juraj Blaho    schedule 26.11.2012
comment
Круто, такое простое решение. Огромное спасибо. - person user1520427; 26.11.2012
comment
Если стек раскручен, разве это не освобождает память сообщения об ошибке, что приводит к недопустимому доступу к памяти? - person Konrad Rudolph; 26.11.2012
comment
@KonradRudolph Lua делает копию сообщения - я думаю. - person user1520427; 26.11.2012
comment
@KonradRudolph: я надеюсь, что сообщение будет скопировано в исключение, выброшенное так же, как если бы вы сами выбрасывали исключение (например: std::runtime_error()). Но я этого не проверял. - person Juraj Blaho; 26.11.2012