Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кстати, по крайней мере в принципе эта ситуация легко разруливается. Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem, то эти указатели можно заменить на смещения относительно начала ListElem, после чего такие элементы можно свопировать.
Даже это нелегко. Например, реализовать CAutoBuffer
таким образом, корректно и без потери эффективности не получится.
Я уже не говорю о том, что элементы списка могут быть довольно большими, и двигать их без особой причины может быть и накладно, а не только некорректно...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>А почему это побитовая? E>Например, где гарантии пересылки прокладок между полями записи?
А они мне на что ? Они unused.
PD>>О господи! Еще раз — имеет место обмен. E>IMHO, не обмен, а обман
Да уж, убийственный аргумент. Видимо, ничего больше не остается...
PD>>Тебе же очень нужно деструктор вызвать. Поэтому придется пойти на обмен. У Вирта только POD, E>Вроде бы у него там на паскале всё было. Так что термин POD там нерелевантен...
PD>>так что достаточно переслать — удаление данных в ListElem у Вирта проблем не вызовет. E>В постановке Вирта такого рода требования на порядок разрушения элементов списка невозможны. E>Но всё равно вызможны требования со стороны аллокатора...
E>>>Почему это все элементы списка всегда имеют один и тот же тип? Скажем список контролов окна чем плох?
PD>>Тебе , видимо, надо азбучные истины объяснять. PD>>Тип элемента списка ListElem. В него, конечно, может входить что угодно, но все элементы списка имеют один и тот же тип — ListElem. Список контролов окна сделать можно, если его поле данных — HWND, или HWND*, или CWnd* или даже CWnd, но тогда только CWnd, а не его наследники. Список из CWnd и CButton сделать нельзя. E>Это почему это нельзя, когда все ими пользуются?
E>Правда изучи что такое интрузивный список. Не будешь таким смешным.
On the other hand, an intrusive container does not store copies of passed objects, but it stores the objects themselves. The additional data needed to insert the object in the container must be provided by the object itself. For example, to insert MyClass in an intrusive container that implements a linked list, MyClass must contain the needed next and previous pointers:
class MyClass
{
MyClass *next;
MyClass *previous;
//Other members...
};
////////////////////////
Ну и при чем здесь это ? Речь шла о списке, имеющем list_node, и о возможности пересылки его полей.
А теперь будь добр привести код, в котором есть класс List, а в нем есть указатель на list_node start, но элемент по этому указателю показывает полем next не на list_node, а на что-то иное.
Код в студию, черт побери!
PD>>Опять деструкторы! При той операции, о которой говорилось, никаких лишних вызовов деструкторов нет. Деструктор вызывается, когда уничтожается объект, а не когда он пересылается в другой элемент списка.
E>Ну как бы тебе пояснить, что НЕ ВСЕ ОБЪЕКТЫ МОЖНО ПЕРЕСЛАТЬ!!!
PD>>Где тут лишние деструкторы ? E>Тут хуже. Тут UB, так как побитовый обмен не POD данных
Доказательства UB в студию. Не рассуждения, а доказательства. Пример, демонстрирующий UB.
Есть два блока памяти, одинакового размера и одинаковой структуры. Будь добр объяснить, почему нельзя один блок памяти переслать в другой при условии, конечно, что нет ссылок на этот блок или его части извне или изнутри него, кроме как ссылок управляющей структуры (списка в данном случае).
Кстати, познакомься на досуге со структурой PE-файлов и назначением секции .reloc. Полезное дело. Узнаешь, как блоки памяти не самой простой структуры перемещают в памяти.
E>А потом некорректно отработают деструкторы.
И это тоже докажи. Был некий объект по адресу P1. Если его деструктировать — все будет корректно. А потом его побитово пересадили по адресу P2, с соблюдением того, что выделено чуть выше. Вот и докажи, что теперь деструктор отработает некорректно.
With best regards
Pavel Dvorkin
Re[35]: Семантика значения есть далеко не у всех объектов ;)
Здравствуйте, Erop, Вы писали:
E>Вот представь себе, что мы пишем какой-то редактор-визуализатор каких-то сложных данных. Данные хранятся в файлах/документах. Ну, например, это редактор/смотрелка описаний гаджетов.
E>Когда мы открываем документ, мы создаём ему view. При этом у документа может быть много view. Все view должны узнавать о том, что документ изменился, чтобы эти изменения отобразить. Поэтому документ будет рассылать уведомления о изменениях в себе
Кому? View ? Бога ради. Или же list_node списка, где хранятся эти view ? Я имеено о последних говорил.
PD>Более того, ситуация, когда извне списка имеются указатели на его ListElem — мягко говоря, не очень хорошая.
E>Это всё довольно обычная архитектура, если честно. Мне странно, что для тебя это всё новость.
Это для меня не новость. Я вполне могу представить и более сложную структуру. Но вот сохранение ссылки на list_node, который вообще не данные, а промежуточная вспомогательная структура, ИМХО не есть хорошее дело, так как дает возможность вмешаться в структуру этого списка помимо его класса List. Что же касается структуры самого элемента данных — это иное дело, он может содержать, что требуется.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Кстати, по крайней мере в принципе эта ситуация легко разруливается. Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem, то эти указатели можно заменить на смещения относительно начала ListElem, после чего такие элементы можно свопировать.
E>Даже это нелегко. Например, реализовать CAutoBuffer
таким образом, корректно и без потери эффективности не получится.
Разбираться нет времени. Объясни в двух словах, почему не получится.
E>Я уже не говорю о том, что элементы списка могут быть довольно большими, и двигать их без особой причины может быть и накладно, а не только некорректно...
Здрасьте, я ваша тетя. Без тебя я бы об этом никак не догадался Вспомни, с чего все начиналось-то...
Кстати, если уж на то пошло, то я вообще не переношу в list_node какие бы то ни было данные размером > 4 байт. (исключение — double). Надо больше — делайте указатель на данные, а по нему хоть иерархию классов разводите. И с размерами проблем не будет, и хранить можно разные типы, и размер всегда 4 байта, и пересылать собственно данные не надо, достаточно переслать указатели. Вот и все.
Здравствуйте, Pavel Dvorkin, Вы писали:
E>>Например, где гарантии пересылки прокладок между полями записи? PD>А они мне на что ? Они unused.
Дык это такое свойство операции, которую обычно понимают под "бинарная пересылка данных". Данные могут же ещё как-то использоваться, а не только из паскаля. Паскаль вообще на таком уровне работать не может. Вы же преподаватель, Павел! Следите за корректностью используемой терминологии. Вас же дети слушают и учатся.
E>>Но всё равно вызможны требования со стороны аллокатора... PD>
Зачем? Программирование, особенно на паскале, бустом никак не ограничивается...
И конструкция, когда у меня есть база, которая умеет сцепляться в списки, и у ней есть много разных наследников -- она совсем-совсем нередкая...
В том числе и при программировании на объектном паскале.
PD>Ну и при чем здесь это ? Речь шла о списке, имеющем list_node, и о возможности пересылки его полей.
Правда? Я вот читаю стартовое сообщение, там про односвязанный список, без уточнения его структуры:
На собеседовании задали задачку:
есть односвязанный список, необходимо его очистить эффективно начиная с конца без привлечения доплонительных внешних ресурсов (например дополнительной памяти).
PD>Код в студию, черт побери!
Ты правда не понимаешь?
struct CListNode {
CListNode* next;
// методы, для работы с узлом односвязанного списка
};
struct CMyAbstractControl : CListNode {
// Тут инфраструктура для работы с моими контролами, например контролами, не являющимися окнами.
};
class CMyListBox : public CMyAbstractControl {
// тут реализация
};
class CMyButton : public CMyAbstractControl {
// тут реализация
};
// и т. д.
PD>Доказательства UB в студию. Не рассуждения, а доказательства. Пример, демонстрирующий UB.
Доказательства простые -- стандарт С++. Бинарная пересылка данных не POD-объекта -- UB...
Пример -- пожалуйста пример. Представь себе, что мои контролы используют CListNode, как виртуальную базу
PD>Есть два блока памяти, одинакового размера и одинаковой структуры. Будь добр объяснить, почему нельзя один блок памяти переслать в другой при условии, конечно, что нет ссылок на этот блок или его части извне или изнутри него, кроме как ссылок управляющей структуры (списка в данном случае).
Потому, что у создателей языка могут быть свои соображения на этот счёт. По стандарту С++ нельзя. Увы.
В паскале вообще странно говорить о блоках памяти.
Кроме того, эти блоки ещё и большими могут быть и пересылать их туда-сюда без всякого повода просто накладно.
PD>Кстати, познакомься на досуге со структурой PE-файлов и назначением секции .reloc. Полезное дело. Узнаешь, как блоки памяти не самой простой структуры перемещают в памяти.
При чём тут это, и то, что не все объекты можно двигать бинарно?
PD>И это тоже докажи. Был некий объект по адресу P1. Если его деструктировать — все будет корректно. А потом его побитово пересадили по адресу P2, с соблюдением того, что выделено чуть выше. Вот и докажи, что теперь деструктор отработает некорректно.
Кури стандарт С++ Там явно сказано, что делать так, как хочешь ты -- UB.
Я понимаю, что ты хочешь сказать. Что в большинстве случаев всё будет хорошо. Я с этим согласен. Но "большинство случаев" и
"можно дать гарантии, что" -- это совсем разные предикаты
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[36]: Семантика значения есть далеко не у всех объектов ;)
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кому? View ? Бога ради. Или же list_node списка, где хранятся эти view ? Я имеено о последних говорил.
view, конечно, вернее тем, кто подпишется. Это не обязательно будут view. Но сами по себе view могут лежать в списке, который просто список и ничего про все эти уведомления не знает.
PD>Это для меня не новость. Я вполне могу представить и более сложную структуру. Но вот сохранение ссылки на list_node, который вообще не данные, а промежуточная вспомогательная структура, ИМХО не есть хорошее дело, так как дает возможность вмешаться в структуру этого списка помимо его класса List. Что же касается структуры самого элемента данных — это иное дело, он может содержать, что требуется.
Дык элемент данных -- это поле неинтрузивного списка. И указатель на это поле, таким образом, является указателем внутрь list_node...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Разбираться нет времени. Объясни в двух словах, почему не получится.
Потому, что содержит внутри себя буффер и указатель на буффер. Когда буффер внутри становится слишком мал, в указатель помещается указатель на аллокированный буфер достаточного размера...
Заменить указатель на смещение не получится потому, что GetPtr() должен работать без ветвления, а вычитать два совсем разных указателя в С++ нельзя.
PD>Кстати, если уж на то пошло, то я вообще не переношу в list_node какие бы то ни было данные размером > 4 байт. (исключение — double). Надо больше — делайте указатель на данные, а по нему хоть иерархию классов разводите. И с размерами проблем не будет, и хранить можно разные типы, и размер всегда 4 байта, и пересылать собственно данные не надо, достаточно переслать указатели. Вот и все.
"Вот и всё" -- это удвоение оверхеда на аллокацию на каждый элемент списка.
Ну и зачем нужна эта лишняя косвенность? Если уж разводить лишний указатель, то лучше список двусвязанным сделать и не страдать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Мы всё ещё обсуждаем требования задачи и как их можно изменить/расширить/сузить и почему или вы уже першли к киданию какашками?
Здравствуйте, Erop, Вы писали:
E>Потому, что содержит внутри себя буффер и указатель на буффер. Когда буффер внутри становится слишком мал, в указатель помещается указатель на аллокированный буфер достаточного размера...
Все, хватит. Я же ясно писал — при отсутствии внешних ссылок и ссылок изнутри.
Я закончил, больше ответов не будет.
With best regards
Pavel Dvorkin
Re[41]: Сейчас же каникулы. Чего ты такой нервный?
Здравствуйте, Pavel Dvorkin, Вы писали:
E>>Потому, что содержит внутри себя буффер и указатель на буффер. Когда буффер внутри становится слишком мал, в указатель помещается указатель на аллокированный буфер достаточного размера...
PD>Все, хватит. Я же ясно писал — при отсутствии внешних ссылок и ссылок изнутри.
Нет, ты писал не совсем так. Посмотри на что я ответил
Ты писал, что обычно можно заменить указатель внутрь объекта смещением. Я привёл тебе пример объекта, с которым так не получится.
Другой пример, когда у тебя внутри объекта есть какие-то библиотечные объекты. Например, контейнеры stl...
PD>Я закончил, больше ответов не будет.
Ну и слава Богу. Видимо ты узнал всё, что хотел
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Господи! Ну поднимись выше по ветке-то!
Сообщение с темой "CAutoBuffer" было ответом на сообщение с темой "P.S."
Вот его текст:
.>>Ты хочешь сказать, что абсолютно любые 2 объекта можно обменять побитово? Ты точно уверен?
PD>Нет, конечно. Если внутри элемента есть указатели на его внутренние поля — конечно нет.
Кстати, по крайней мере в принципе эта ситуация легко разруливается. Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem, то эти указатели можно заменить на смещения относительно начала ListElem, после чего такие элементы можно свопировать.
И я показал тебе, что вполне бывают ситуации, когда эта байда не разруливается. Ни в принципе ни не в принципе, ни никак ещё...
Удачного вам семестра, Павел.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Господи! Ну поднимись выше по ветке-то! E>Сообщение с темой "CAutoBuffer" было ответом на сообщение с темой "P.S." E>Вот его текст:
.>>Ты хочешь сказать, что абсолютно любые 2 объекта можно обменять побитово? Ты точно уверен?
PD>>Нет, конечно. Если внутри элемента есть указатели на его внутренние поля — конечно нет.
E>Кстати, по крайней мере в принципе эта ситуация легко разруливается. Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem, то эти указатели можно заменить на смещения относительно начала ListElem, после чего такие элементы можно свопировать.
E>И я показал тебе, что вполне бывают ситуации, когда эта байда не разруливается. Ни в принципе ни не в принципе, ни никак ещё...
Уф! Пришлось все же разобраться с этим буфером.
Нет, ничего ты не показал. Повторяю сказанное ыыше : "Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem"
А у тебя ptr показывает то ли на что-то внутри структуры, то ли куда-то во внешний мир. О таких случаях я не говорил.
А вообще сказанное мной довольно-таки банально. Почитай в MSDN про based указатели. Там, правда, 64 бита вместо 32, но идея именно эта — база и смещение. Вот кусочек
For the Microsoft 32-bit and 64-bit C compilers, a based pointer is a 32-bit or 64-bit offset from a 32-bit or 64-bit pointer base. Based addressing is useful for exercising control over sections where objects are allocated, thereby decreasing the size of the executable file and increasing execution speed. In general, the form for specifying a based pointer is
type__based(base)declarator
The "based on pointer" variant of based addressing enables specification of a pointer as a base. The based pointer, then, is an offset into the memory section starting at the beginning of the pointer on which it is based. Pointers based on pointer addresses are the only form of the __based keyword valid in 32-bit and 64-bit compilations. In such compilations, they are 32-bit or 64-bit displacements from a 32-bit or 64-bit base.
One use for pointers based on pointers is for persistent identifiers that contain pointers. A linked list that consists of pointers based on a pointer can be saved to disk, then reloaded to another place in memory, with the pointers remaining valid.
Как тебе последняя фраза ?
E>Удачного вам семестра, Павел.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Уф! Пришлось все же разобраться с этим буфером. PD>Нет, ничего ты не показал. Повторяю сказанное ыыше : "Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem"
Ну если ты таки разобрался, то покажи, как положить в твой список CAutoBuffer, или, хотя бы std::string...
PD>One use for pointers based on pointers is for persistent identifiers that contain pointers. A linked list that consists of pointers based on a pointer can be saved to disk, then reloaded to another place in memory, with the pointers remaining valid. PD>Как тебе последняя фраза ?
Советую поэкспериментировать на сегментной памяти
Конечно, если у тебя вся структура лежит в ОДНОМ куске памяти, то можно юзать смещения, а вот если не вся или не в одном, то опа...
E>>Удачного вам семестра, Павел. PD>И вам успехов в освоении программирования!
Эх, Павел, Павел. Я-то желал вам удачи, как преподавателю. Но учиться тоже никогда не поздно
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, McSeem2, Вы писали:
MS>Короче говоря, единственное нормальное решение задачи — инвертировать список, после чего пришибить от начала к концу. O(n) времени O(1) памяти. Любые другие решения являются больными. И вот закидайте меня помидорами — лучшего решения не существует в силу устройства этого вашего мира.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Уф! Пришлось все же разобраться с этим буфером. PD>>Нет, ничего ты не показал. Повторяю сказанное ыыше : "Если в ListElem есть поля, являющиеся указателями на что-то внутри ListElem" E>Ну если ты таки разобрался, то покажи, как положить в твой список CAutoBuffer, или, хотя бы std::string...
Прочти вышесказанное еще раз. Выделил специально.
PD>>One use for pointers based on pointers is for persistent identifiers that contain pointers. A linked list that consists of pointers based on a pointer can be saved to disk, then reloaded to another place in memory, with the pointers remaining valid. PD>>Как тебе последняя фраза ?
E>Советую поэкспериментировать на сегментной памяти E>Конечно, если у тебя вся структура лежит в ОДНОМ куске памяти, то можно юзать смещения, а вот если не вся или не в одном, то опа...
Уф... Microsoft Specific для Win32/64 и сегментная память .
Структура, лежащая не в одном куске. offsetof плачет горючими слезами.
E>>>Удачного вам семестра, Павел. PD>>И вам успехов в освоении программирования! E>Эх, Павел, Павел. Я-то желал вам удачи, как преподавателю. Но учиться тоже никогда не поздно
Эх, Егор! Я тоже искренне желаю Вам удачи в освоении реального программирования, а не схоластического обсуждения стандарта языка. Могу посоветовать еще принять участие, скажем, в форуме по Win32 — там схоластику не очень любят, потому как решают реальные задачи
Здравствуйте, Pavel Dvorkin, Вы писали:
E>>Ну если ты таки разобрался, то покажи, как положить в твой список CAutoBuffer, или, хотя бы std::string...
PD>Прочти вышесказанное еще раз. Выделил специально.
Лучше ты прочти выделенное
Или ты std::string тоже считаешь "неинтересным частным случаем"?
PD>Уф... Microsoft Specific для Win32/64 и сегментная память .
А! Так мы про списки исключительно под плоскую память тут обсуждаем? Ну ты бы предупредил, что ли
Вообще-то ситуация, когда в объекте есть указатель внутрь себя, она довольно частая именно в том случае, когда в объекте есть какой-то буфер и указатель внутрь этого буфера, а если буфера не хватила, то и куда-то вовне
PD>Структура, лежащая не в одном куске. offsetof плачет горючими слезами.
Почему обязательно именно struct? Данные могут иметь и более замысловатую структуру
Ещё раз предлагаю посмотреть на такой класс, как std::string, в некоторых популярных реализациях он работает с памятью так же, как и CAutoBuffer!
Просто академически можно рассуждать о таком списке и другом списке, но на практике списки, которым нужна возможность бинарно пересылать данные неприемлемы.
PD>Эх, Егор! Я тоже искренне желаю Вам удачи в освоении реального программирования, а не схоластического обсуждения стандарта языка. Могу посоветовать еще принять участие, скажем, в форуме по Win32 — там схоластику не очень любят, потому как решают реальные задачи
При чём тут схоластика? Я совершенно практически программирую, просто мой код портится потом под очень многие платформы. Например под многие телефоны и другие мобильные устройства...
Ну а писать список в расчёте на привязку именно к Win32 -- это, IMHO, безумие.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Qwazar, Вы писали:
Q>Слышал схожую задачу, с таким же некорректно сформулированным условием. Решение предполагалось такое как тут: http://www.rsdn.ru/forum/etude/3913898.aspx
Здравствуйте, Erop, Вы писали:
PD>>Прочти вышесказанное еще раз. Выделил специально. E>Лучше ты прочти выделенное E>Или ты std::string тоже считаешь "неинтересным частным случаем"?
Копаться в нем внутри нет времени, но скорее всего, там ничего особого нет.
Кстати, что касается CAutoBuffer. Если не секрет — какой глубокий смысл имеет char buffer[standardBufferSize]; и почему бы не сделать standardBufferSize параметром конструктора класса (с возможным значением по умолчанию) вместо того, чтобы параметром темплейта, и выделять под него память в конструкторе. По крайней мере можно будет управлять этим стандартным размером в рантайме, это раз. Но есть и второе. не мог бы ты объяснить, зачем ты транжиришь память на char buffer[standardBufferSize] в случае, когда его размера не хватило ? Завел новый буфер, а этот бы освободить, и дело с концом. Да нельзя.
PD>>Уф... Microsoft Specific для Win32/64 и сегментная память . E>А! Так мы про списки исключительно под плоскую память тут обсуждаем? Ну ты бы предупредил, что ли
. М-да...
E>Вообще-то ситуация, когда в объекте есть указатель внутрь себя, она довольно частая именно в том случае, когда в объекте есть какой-то буфер и указатель внутрь этого буфера, а если буфера не хватила, то и куда-то вовне
См. выше.
PD>>Структура, лежащая не в одном куске. offsetof плачет горючими слезами. E>Почему обязательно именно struct? Данные могут иметь и более замысловатую структуру
Это ты писал ?
E>Конечно, если у тебя вся структура лежит в ОДНОМ куске памяти, то можно юзать смещения, а вот если не вся или не в одном, то опа...
E>При чём тут схоластика? Я совершенно практически программирую, просто мой код портится потом под очень многие платформы. Например под многие телефоны и другие мобильные устройства...
Успеха! И давай закончим дискуссию.
E>Ну а писать список в расчёте на привязку именно к Win32 -- это, IMHO, безумие.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Копаться в нем внутри нет времени, но скорее всего, там ничего особого нет.
Плохо. Я тебе на примере уже третий день объясняю, как оно работает, а у тебя всё равно "ничего особого нет"...
PD>Кстати, что касается CAutoBuffer. Если не секрет — какой глубокий смысл имеет char buffer[standardBufferSize];
Не секрет. Фишка в том, что аллокация -- это очень дорого. А буфер на стеке -- нет. Это одна из популярных техник, которая в С++ позволяет обойтись без alloca, без потери эффективности.
Сценарий использования такой. Пусть у тебя есть какая-то задача, требующая буфера, который обычно легко помещается на стеке, но иногда может быть сколь угодно большим. Например тебе надо обработать по одной строки в каком-нибудь текстовом файле. Ты заводишь CAutoBuffer с таким параметром, чтобы в обычном случае данные поместились в его внутренний буфер. И при использовании, говоришь ему какого размера нужен буфер и получаешь требуемое.
В результате, в обычных случаях, когда данных мало (строки в файле нормальной длины, не больше 4К, например) ты работаешь на стеке и не тратишь время на аллокации, а в редких случаях, когда данных много, работаешь на буфере, выделенном на куче. При этом, это всё происходит прозрачным для клиентского кода образом, за исключением того, что в первом режиме экземпляр CAutoBuffer содержит внутри себя указатель на себя же.
Так как большинство строк в программах короткие, то некоторые реализации STL используют аналогичную технику для std::string (в смысле для std::basic_string), то есть в экземпляре строки есть буффер, и если строка коротка, то используется он, а если нет, то используется буфер аллокированый на аллокаторе.
PD>>>Структура, лежащая не в одном куске. offsetof плачет горючими слезами. E>>Почему обязательно именно struct? Данные могут иметь и более замысловатую структуру
E>>Конечно, если у тебя вся структура лежит в ОДНОМ куске памяти, то можно юзать смещения, а вот если не вся или не в одном, то опа...
Это просто омонимия. Имелась в виду структура данных.
E>>Ну а писать список в расчёте на привязку именно к Win32 -- это, IMHO, безумие. PD>Уф...
Думаешь не безумие?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском