Я использую библиотеку Jansson в моем коде C ++. В библиотеке, когда создается любая переменная Jansson, переменная должна быть освобождена, чтобы освободить ссылку, и я использую метод ‘json_decref (json_t * json)’ для освобождения.
Но иногда это вызывает проблему двойного освобождения, и я не получил проблему во время выполнения. Возможно, это не нормально, но я хочу получить ошибку во время выполнения, когда пытаюсь освободить некоторые ссылки. Например, я запускаю следующий тестовый код,
json_t *root = json_loads(any_json_message, 0, &error);
json_decref(root);
json_decref(root);
Как вы видите, есть проблема, и я не получаю никаких ошибок во время выполнения, как double free.
Кроме того, я использую CMake для компиляции моего исходного кода. Может быть, любой флаг cmake исправит мой вопрос.
Любая идея ?
Поведение доступа к указанному объекту не определено после его освобождения. Документация не разъясняет это, но вызывает json_decref
более одного раза (плюс количество звонков json_incref
на указатель) также имеет неопределенное поведение.
Возможно, это не нормально, но я хочу получить ошибку во время выполнения, когда пытаюсь освободить некоторые ссылки.
Ну, Янссон не дает это тебе.
Ваш компилятор может предоставить анализатор времени выполнения, который сможет обнаружить некоторое неопределенное поведение и завершить программу сообщением. Смотрите руководство вашего компилятора для того, как использовать анализатор.
В документации сказано, что json_t
содержит количество ссылок. Я думаю, что первый звонок json_decref
уменьшает счетчик ссылок с 1 до 0 и освобождает память. Второй звонок json_decref
видит, что счетчик ссылок равен 0, и ничего не делает.
Чтобы сгенерировать ошибку double-free, вы должны скопировать старое содержимое json_t
объект. Примерно так (но не буквально; см. Ниже):
json_t *root = json_loads(any_json_message, 0, &error);
json_t copy = *root;
json_decref(root);
json_decref(©);
Тем не мение, json_t
это (я думаю) непрозрачный тип, то есть пользователи могут создавать только указатели на него, а не объекты. Чтобы принудительно создать копию объекта, вы можете угадать размер json_t
объект и использование memcpy
:
json_t *root = json_loads(any_json_message, 0, &error);
char copy[42];
memcpy(copy, root, sizeof copy);
json_decref(root);
json_decref((json_t *)copy);
Попробуйте с различными размерами (вместо 42), пока он не работает. Однако я не уверен, что вы можете заставить его работать — это всего лишь предположение о том, как работают внутренние компоненты этой библиотеки.