Одна ловушка с alloca
заключается в том, что longjmp
перематывает его.
То есть, если вы сохраняете контекст с помощью setjmp
, затем alloca
некоторой памяти, а затем longjmp
в контексте, вы можете потерять alloca
память (без какого-либо уведомления). Указатель стека возвращается туда, где он был, и поэтому память больше не резервируется; если вы вызываете функцию или делаете другую alloca
, вы закроете оригинал alloca
.
Чтобы уточнить, что я здесь конкретно имею в виду, это ситуация, когда longjmp
не возвращается из функции, в которой имел место alloca
! Скорее функция сохраняет контекст с setjmp
; затем выделяет память с помощью alloca
и, наконец, longjmp имеет место для этого контекста. Память этой функции не полностью освобождена; просто вся память, которую он выделил со времен setjmp
. Конечно, я говорю о наблюдаемом поведении; ни одно из таких требований не задокументировано ни в одном alloca
, которое я знаю.
В документации основное внимание обычно уделяется концепции, согласно которой alloca
память связана с активацией функции , , а не с каким-либо блоком; что множественные вызовы alloca
просто захватывают больше стековой памяти, которая освобождается после завершения функции. Не так; память фактически связана с контекстом процедуры. Когда контекст восстанавливается с помощью longjmp
, то же происходит с предыдущим состоянием alloca
. Это является следствием того, что сам регистр указателя стека используется для выделения, а также (обязательно) сохраняется и восстанавливается в jmp_buf
.
Между прочим, это, если оно работает таким образом, обеспечивает правдоподобный механизм для преднамеренного освобождения памяти, которая была выделена с помощью alloca
.
Я столкнулся с этим как с основной причиной ошибки.
Как вы распечатываете содержимое вашего XDocument
?
Метод .ToString ()
не включает заголовок xml, но Метод .Save ()
выполняет.
Изменить: Такой же ответ был дан здесь .
Вы пытались сохранить XDocument?
xDocument.Save("books.xml");
Посмотрите на этот вопрос how-to-print-xml-version1-0-using-xdocument
Вот документация: Метод XDocument.Save
Как это сохранить? Если я сделаю следующее, объявление xml будет выглядеть так, как должно:
XDocument xDocument = new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("Books"));
xDocument.Save(@"c:\temp\file.xml");
Результат выглядит следующим образом:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Books />
Однако, если я вместо этого передаю экземпляр XmlWriter, кажется, что настройки для этого XmlWriter переопределяют то, что указано в XDocument:
XDocument xDocument = new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("Books"));
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))
{
xDocument.Save(writer);
}
Console.WriteLine(sb.ToString());
Вывод выглядит следующим образом:
<?xml version="1.0" encoding="utf-16" standalone="yes"?><Books />
Обратите внимание, как кодировка изменилась на «utf-16» и изменился отступ. Если вы добавите экземпляр XmlWriterSettings, указывающий кодировку (и любые другие параметры, которыми вы хотите управлять), вы получите лучший результат. Следующий код делает то, что вы ожидаете:
XDocument xDocument = new XDocument(
new XDeclaration("1.0", "UTF-8", "yes"),
new XElement("Books"));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = Encoding.UTF8;
settings.ConformanceLevel = ConformanceLevel.Document;
settings.Indent = true;
using (XmlWriter writer = XmlWriter.Create(@"c:\temp\xdocument.xml", settings))
{
xDocument.Save(writer);
}
Вывод:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Books />