Как исправить проблемы с владением RapidXML String? - PullRequest
7 голосов
/ 12 марта 2010

RapidXML - быстрый и легкий анализатор C ++ XML DOM, но в нем есть некоторые особенности.

Худшее из них, на мой взгляд, таково:

3.2 Право собственности на строки.

Узлы и атрибуты, создаваемые RapidXml, не владеть их именем и строкой значений. Oни просто держите указатели на них. это означает, что вы должны быть осторожны, когда установив эти значения вручную, используя xml_base::name(const Ch *) или xml_base::value(const Ch *) функции.

Необходимо позаботиться о том, чтобы время жизни переданной строки составляет хотя бы до тех пор, как жизнь узел / атрибут. Самый простой способ добиться этого, чтобы выделить строку из memory_pool, принадлежащей документ. использование memory_pool::allocate_string() функция для этой цели.

Теперь я понимаю, что так сделано для скорости, но это похоже на автомобильную аварию, ожидающую своего появления. Следующий код выглядит безобидным, но «name» и «value» выходят из области видимости, когда возвращается foo, поэтому документ не определен.

void foo()
{
  char name[]="Name";
  char value[]="Value";

  doc.append_node(doc.allocate_node(node_element, name, value));
}

Предложение использовать allocate_string() согласно ручным работам, но это так легко забыть.

Кто-нибудь «улучшил» RapidXML, чтобы избежать этой проблемы?

1 Ответ

1 голос
/ 23 апреля 2010

Я не использую RapidXML, но, возможно, мой подход может решить вашу проблему.

Я начал использовать Xerces, но я обнаружил, что он тяжел, помимо других мелких неприятностей, поэтому я перешел в CPPDOM. Когда я сделал это, я решил создать набор классов-оболочек, чтобы мой код не зависел от конкретного «движка» XML, и при необходимости я мог бы портировать на другой.

Я создал свои собственные классы для представления базовых объектов DOM (узла, документа и т. Д.). Эти классы внутренне используют идиому pimpl для использования объектов CPPDOM. Поскольку мой объект узла содержит «реальный» объект узла (из CPPDOM), я могу управлять чем угодно, поэтому правильное распределение и освобождение строк не будет проблемой там.

Поскольку мой код для CPPDOM, я не думаю, что он будет для вас очень полезным, но я могу опубликовать его, если хотите.

Кстати, если у вас уже слишком много кода, который уже использует RapidXML, вы можете воспроизвести его интерфейсы в ваших классах-оболочках. Я этого не делал, потому что код, который использовал Xerces, был не таким длинным, и мне все равно пришлось бы его переписать.

...