Свежие комментарии

Title Comment
Это значит, что у тебя не хватает третьего элемента абстракц

Это значит, что у тебя не хватает третьего элемента абстракции - "RAW_file" или что-то типа того.

Иначе и не было этой хрени с "бесхозным free()".

<b>>> Как тут уже написали, libc - часть системы. Есть всегд

>> Как тут уже написали, libc - часть системы. Есть всегда.
То бишь, free() всегда один... <<

это если связывание статическое.
А если не статическое, то будет ровно тот же "бардак и катастрофа" что и у мелкомягких.

не так ли?

чёт ты уже откровенно психуешь и тупишь. fread скомпилирова

чёт ты уже откровенно психуешь и тупишь.

fread скомпилирован в том же environment, что и fopen, так что "контракт" между ними не нарушен... либо оба пойдут через "дебагнутую" либу, либо - через "релизную", "многопоточную", "многоядерную" и ты.ды.

прикладной код вообще не должен делать никаких предположений

прикладной код вообще не должен делать никаких предположений относительно реализации.
Сегодня у тебя там open(...), а завтра - sopen() какой-нибудь или ещё какая хрень.

Так что херня - это когда один "аллокирует", а другой - "деаллокирует"... а потом третий сидит и "рвёт на ж. волосы" в попытках развязать этот порочный круг.

Да что вы с этми виндами

Да не хочет он другую версию. Ну не так это в UNIX'ах работает как в винде - что вы на этом зациклились. При загрузке DLL в UNIX происходит динамическая линковка, причем в отличие от виндов она полноценна - с настоящим линкером и разборкой символов. Поэтому привязка идет не к конкретной версии библиотеки а к символу (функция с определенной сигнатурой, глобальный символ с роеделенным именем и типом итп). Вся эта туфта как в виндах по привязке к номкру или функции и версии и имени библиотеки тут не нужна. Линкер просто найдет символ в библиотеке и слинкует а если сингатура не совпадет то нет. Все просто и работает более надежно. Пожтому неважно из какой версии libc вы использовали malloc/free - их сигнатура не менялась уже лет 40.

Я затрудняюсь насчет

Я затрудняюсь насчет счастливого конца. GNU+STLport - скорее всего счастливого конца не будет.
А связь со сложностью такая, что STL в интерфейсах - можно, а как обеспечить работу разных имплементаций (не строго одной с экспортом, а именно разных) - непонятно.

Вот как офигачить простые структуры данных без ассоциированного с ними инстанционированного кода - более-менее понятно, берешь и офигачиваешь, всего-то надо смещения полей данных одинаковые по всему коду.

Про Дельфи плохо знаю, а смешать C, Fortran и Pascal можно без особых проблем.

По поводу MS STL/GNU

По поводу MS STL/GNU STL/STLport - да, секас будет, но вроде со счастливым концом.

По поводу сложности C++, может оно и так, но я не вижу взаимосвязи этого высказывания с обсуждаемой проблемой.
Имхо все эти проблемы возможны и в других императивных/ОО языках.
Например, наверняка проблемы будет при смешивании Deplhi/FreePascal, FreePascal/GNUPascal, FreePascal'и разных версий.

Даже если экспортировать.

Даже если экспортировать.
Компонент1 использует MS STL и его экспортирует. Поставляется в бинарном виде...
Компонент2 использует GNU STL и его экспортирует. Поставляется и в исходниках тоже, но компилируется только gcc :)
Приложение использует STLport и готово что-то поимпортировать.....

Ужас же, нах.

C++ получился слишком сложным языком, на мой взгляд. Ну я вот лично давно отчаялся за ним даже следить, но ведь это говорят и те, кто следит.

Да, зло. "Чистые" интерфейсы

Да, зло. "Чистые" интерфейсы лучше(всё зависит от задач..), как минимум более портабельно между разными языками.
Но изобретать свои stl-подобные классы, из-за проблем с разными crt (вроде тут кто-то предлагал), в то время когда можно использовать stl (аллокаторы, экспорт специализаций, ну максимум простой врапер), не меньшее зло.

STL в интерфейсах - вообще

STL в интерфейсах - вообще зло.

Реализация

Но возможна также проблема с разными реализациями std::vector.
Конечно в этом случаем можно попробовать экспортировать его из библиотеки(специализацию).

<i>Ну, тогда тот, кто по недомыслию линкуется с двумя версия

Ну, тогда тот, кто по недомыслию линкуется с двумя версиями crt...

Ну а как - вот пришел 3rd-party DLL, с чем он там слинкован - вовсе неведомо...

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

<i>Так ведь маллок/фрии связываются статически. Разве нет ?<

Так ведь маллок/фрии связываются статически. Разве нет ?

В юниксах - нет.
В виндах - тоже нет, но в разных кусках приложения может быть разный рантайм.

Allocation

Кучи разные(наверняка уже кто-то ответил).
Вы видели, например у std::vector, второй шаблонный параметр?

template < class T, class Allocator = allocator > class vector;
А сам объект allocator'а, можно передавать в конструкторах.

Вот, как раз для борьбы с разными кучами при разных CRT, можно использовать одинаковые allocator'ы (в частности при использовании STL).

<b>>> И я привык, что в исполняемом образе (после динамическ

>> И я привык, что в исполняемом образе (после динамической линковки) будет один malloc(), один free() ну и так далее. <<
Так ведь маллок/фрии связываются статически. Разве нет ?

PS: if(p) free(p) - здесь if() избыточный. free() не падает по NULL. это стандарт.

<b>>> Но при этом - нет никаких проблем слинковать в приложе

>> Но при этом - нет никаких проблем слинковать в приложение сразу две эти библиотеки <<
что-то я не понял прикола.
В чём проблема ? - релизная и дебагная компиляция транслируют тот же malloc/free в разные символические имена ?
Ну, тогда тот, кто по недомыслию линкуется с двумя версиями crt, сам себе Злобный Баклан Буратино.
Если же символические имена будут одинаковые, то проблем быть не должно даже в случае линковки с двумя либами (возьмётся первая попавшаяся).

Так всегда и везде было. В той же джаве можно подсунуть две версии одного и того же класса и тоже никто не возбухнет (есть там какие-то механизмы, но ими, кажется, реально никто не пользуется. да и предназначены они для другого).

-+-
>> А, да, сухой остаток, сижу выпиливаю в LibRaw зеркальный вызов, который будет освобождать аллоцированное строго правильным освободителем. Две строчки кода, блин. <<
на мой взгляд это вообще плохая практика когда "аллоцирцет ресурс" один агент (библиотека, напр.) а освобождает его - другой (клиентский код, напр.), поелику нарушает принцип "loosely coupled" и прочие CRC.

так что вообще-то это ты не прав, а не мелкомяХкие.

О том, что в смысле языка free заменит deletе речи нет, есте

О том, что в смысле языка free заменит deletе речи нет, естественно никаких деструкторов никто не вызовет. Тут можно лишь говорить о целостности кучи, а если в C код попадает указатель на объект, то это уже проблема дизайна. Вообще в С/C++ чувствуется слабая проработка всех этих нюансов связанных со связыванием модулей, управление памяти во многом должно контроллироваться правильными действиями программиста и стандарт тут не помогает.

В c++0x есть что-то о сборщиках мусора, но не факт что это имеет отношение к данной проблеме.

Да, но это уже поведение более высокого уровня, непосредстве

Да, но это уже поведение более высокого уровня, непосредственно к структуре блоков памяти не должно иметь отношения.

Ясно, так можно частично решить проблему именно с кучей, есл

Ясно, так можно частично решить проблему именно с кучей, если все договорятся использовать эти аллокаторы. Но во-первых надо именно перейти на них, а во-вторых может это и не решить проблемы т.к. поверх "низкоуровнего" аллокатора может лежать дополнительный слой - я имею ввиду например дебажный alloc/free, который в заголовке содержит доп. инфу, следовательно освобождаться должен симметричным образом. Вобщем подход с унификацией нижнего слоя может прокатить, но это требует некой стандартизации.

new/malloc могут брать памяти больше чем было запрошено, то

new/malloc могут брать памяти больше чем было запрошено, то есть malloc(x) захватит p размером x+i и вернет указатель на p+i, в p[0-i] служебная инфа.
Чтобы не делать этого для мелких блоков, можно держать несколько куч с быстрым определением из какой кучи данный блок.

Сомневаюсь правда, что такое сделают чтобы кто-то мог смешивать delete/free. :)

А откуда free() узнает, что ему подсунули указатель на класс

А откуда free() узнает, что ему подсунули указатель на класс (с деструктором)?
Там же this не будет.

Догадается? Опасное это дело.....

Фатального наверное нет, но если был выделен обьект - дестру

Фатального наверное нет, но если был выделен обьект - деструктор отрабатывать не должен. Хотя возможно в каких-то рантаймах это делают.

Я проверял, вызов ядра из HeapAlloc (ntdll!RtlAllocateHeap)

Я проверял, вызов ядра из HeapAlloc (ntdll!RtlAllocateHeap) происходит редко.
Там реализован немаленький user-mode memory manager.

Не, я о том, что просто аллокатор действительно несложно пер

Не, я о том, что просто аллокатор действительно несложно переопределить, а вот с плюсами гемороя в этом месте слишком уж много и лучше бы доверить это дело libstdc++ или как ее там зовут.

Думаю речь о принципиальной возможности использовать инвариа

Думаю речь о принципиальной возможности использовать инвариант. new/delete я думаю просто добавляет некоторое дополнительное поведение поверх обычной аллокации, мне кажется даже если вызвать free для памяти выделенной через new ничего фатального не произойдет, хотя понятно что такое делать не нужно. Я могу ошибаться, но мне кажется new никак не влияет на стурктуру блока.

Переопределение это можно использовать только если везде брать ее за основу, если имеем уже реализованый код на alloc/free, new/delete то придется под него подстраиваться.

Граждане, ну malloc/free так еще можно заменить, но ведь ест

Граждане, ну malloc/free так еще можно заменить, но ведь есть new/delete.

Да, это тоже вариант, но для памяти думаю не самый эффективн

Да, это тоже вариант, но для памяти думаю не самый эффективный способ, т.к. цена вызова в ядро намного выше.

> Заметим себе, что под вендами чудесным образом поведение п

> Заметим себе, что под вендами чудесным образом поведение программы у меня меняется от включения отладки по memory leak. Очень сексуально, когда релизная версия работает, а отладочная - нет.

Если я верно понимаю, то ты говоришь не о смешении разных crt в рамках одного процесса, а именно о замене crt release на crt debug. Если это так, то вообще при переходе от release к debug разные интересные вещи происходят. Ошибки проявляющиеся в релизе могут не происходить в дебаге, обычно воспроизводимость в дебаге намного лучше. В дебаге аллоцируемая память заполняется константой, кроме того адреса будут немного другими при запуске, поэтому ошибки на указателях по другому будут себя вести, от оптимизации кода тоже изменения в адресах будут, вобщем всякие чудесные ошибки при работе с памятью могут в дебаге и релизе отличаться. Такая проблема была всегда - рано или поздно выскакивает какая-нибудь заковыристая проблема которая плохо воспроизводится и при попытке отладки ускользает.

В windows есть еще вариант пользоваться HeapAlloc/HeapFree и

В windows есть еще вариант пользоваться HeapAlloc/HeapFree и HANDLE для файлов.
Ну не posix конечно.

Стандартный линкер не даст нормально смешать разные версии б

Стандартный линкер не даст нормально смешать разные версии библиотек.

Т.е. да, это можно сделать, влинковав одну "dll" в другую статически (возможно), но это удивительный секс.
И в этом случае, действительно, можно будет добиться, что malloc() в одном модуле несовместим с free() в другом.

Но для этого нужно специально постараться, само так не получится.

Заметим себе, что под вендами чудесным образом поведение программы у меня меняется от включения отладки по memory leak. Очень сексуально, когда релизная версия работает, а отладочная - нет.

Pages

Subscribe to comments_recent_new