Чисто виртуальный вызов функции с помощью JSonCpp

#c #windows #runtime-error #jsoncpp

#c #Windows #ошибка во время выполнения #jsoncpp

Вопрос:

Я продолжаю получать это, когда закрываю свое приложение. Я знаю, что это как-то связано с JsonCpp, поскольку это происходит только тогда, когда я использую значения Json.

Я думаю, что это как-то связано с тем, как я создаю значение json, но поскольку на самом деле нет никаких руководств, я понятия не имею, как мне это сделать

Мой код в настоящее время:

 static Json::Value root;   // will contains the root value after parsing.

unsigned int WindowSettings::WindowWidth = 800;
unsigned int WindowSettings::WindowHeight = 600;
bool WindowSettings::FullScreen = false;
unsigned short WindowSettings::AntiAliasing = 16;
bool WindowSettings::VSync = false;
short WindowSettings::FrameRateLimit = 60;
AspectRatios WindowSettings::AspectRatio = ar4p3;
Resolutions WindowSettings::Resolution = r800x600;
Json::Value WindowSettings::root = Json::Value();

void WindowSettings::remakeDefault()
{
    root["WindowWidth"] = WindowWidth;
    root["WindowHeight"] = WindowHeight;
    root["FullScreen"] = FullScreen;
    root["AntiAliasing"] = AntiAliasing;
    root["VSync"] = VSync;
    root["FrameRateLimit"] = FrameRateLimit;
    root["AspectRatio"] = AspectRatio;
    root["Resolution"] = Resolution;
    saveToFile("conf.json");
}

bool WindowSettings::saveToFile(const std::string amp;fileName)
{
    Json::FastWriter writer;
    // Make a new JSON document for the configuration. Preserve original comments.
    std::string outputConfig = writer.write( root );

    std::ofstream myfile;
    myfile.open (fileName.c_str(), std::ios::out | std::ios::trunc | std::ios::binary );
    if (myfile.is_open())
    {
        myfile << outputConfig.c_str();
        myfile.close();
    }
    return true;
}
  

Я должен добавить, что этого не происходит, когда я не выполняю:
root[«blah»] = foo;

Комментарии:

1. …. там нет root["blah"] = foo ?!

Ответ №1:

Редактировать

Найдено, что это известная проблема (например, здесь)

Оказывается, это связано с какой-то ошибкой в jsoncpp, из-за которой он не работает как глобальные переменные. Я полагаю, что от старого представления о том, что глобальные переменные — это плохие новости, трудно избавиться. Итак, я убрал весь свой json из глобальных файлов, и теперь он работает нормально. Меньшее количество глобалов, безусловно, является хорошим шагом *, в любом случае.

Сообщение об ошибке здесь (zeromus): http://sourceforge.net/tracker/index.php?func=detailamp;aid=2934500amp;group_id=144446amp;atid=758826

Статус ИСПРАВЛЕН:

Я исправил это, представив тот факт, что значение имеет неявную зависимость от данного экземпляра ValueAllocator , присвоив ему ValueAllocatorHandle, который просто подсчитывает ссылки и заботится об удалении распределителя, выделенного в куче, когда последнее значение выходит за пределы области видимости.


В общем, я подозреваю, что конструктор / деструктор обращается к виртуальным членам, ведущим к UB (и, возможно, вообще отсутствует виртуальный деструктор).

Поскольку вы упомянули завершение работы приложения, static Json::Value root это подозрительно. Если это в Linux, я бы запустил его под valgrind

 sudo -E valgrind --db--attach=yes ./yourprogram
  

Это гарантирует, что у вас есть необходимые разрешения. Конечно, это помогает (очень) компилировать с отладочной информацией.

Комментарии:

1. В настоящее время я работаю в Windows с использованием VS2010, я запустил его в режиме отладки, но на самом деле он не дает мне много информации. Использование функции break приводит меня сюда, если (rterrnum != _RT_CRNL amp;amp; rterrnum != _RT_BANNER amp;amp; rterrnum != _RT_CRT_NOTINIT) { switch (_CrtDbgReportW(_CRT_ERROR, NULL, 0, NULL, error_text)) { случай 1: _CrtDbgBreak(); msgshown = 1; break; случай 0: msgshown = 1; break; } } В частности, случай 1

2. Итак, на что root["blah"] = foo вы ссылаетесь?

3. Под root[«blah»] = foo я имел в виду все вещи в remakeDefault. т.е. root[«windowWidth»] = windowWidth; root[«windowHeight»] = windowHeight; root[«FullScreen»] = Полноэкранный режим; root[«Сглаживание»] = сглаживание; root[«VSync»]= VSync; root[«FrameRateLimit»] = FrameRateLimit; root[«aspectRatio»] = aspectRatio; root[«Resolution»] = Разрешение;

4. @Richy19: эта трассировка стека находится ниже точки, в которой она была запущена. Поднимитесь на (несколько) фреймов в callstack ( Debug/Views/Call Stack ) Вы не упоминаете, что вызывает разрыв. Отображается ли диалоговое окно debug assert? Пожалуйста, упомяните такие важные вещи 🙂 ( О, и, пожалуйста, не вставляйте код в комментарии, особенно не избыточный код ? Спасибо)

5. Стек вызовов: [ссылка] pastebin.com/NTkLLTf9 Извините за код, я все еще новичок в SOF, поэтому пытаюсь освоиться