Вот вопрос...

Обсуждения по программированию для ОС Windows безотносительно используемого языка программирования. Windows NT, Win32, Windows API, ядро и драйверы.
iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Вот вопрос...

Сообщение iGrok » 30.09.2010 (Чт) 0:19

Насчёт строк. Выделяй globalalloc'ом, и освобождай globalfree. И никаких проблем.
Другой вопрос, что хорошим тоном, вроде как, считается освобождение памяти на том же уровне, где она выделялась, но это не аксиома.
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Вот вопрос...

Сообщение Хакер » 30.09.2010 (Чт) 0:26

iGrok писал(а):Насчёт строк. Выделяй globalalloc'ом, и освобождай globalfree. И никаких проблем.

Буэ, она устарела.

Канонические решения здесь такие:
  1. Вызываемая функция не выделяет память, а получает указатель на (заранее выделенный вызывающей стороной) буфер. И пишет туда, если размер подходящий. Соответственно, отвечает за буфер вызывающая сторона.
  2. Для любой функции, которая что-то выделяет, создаётся парная функция, которая это что-то уничтожает. CreateXXX/DestroyXXX.
  3. В COM исповедуется концепция аллокатора: есть объект-аллокатор, поддерживающий интерфейс IMalloc. И вызывающая, и вызываемая сторона владеет аллокатором, так что память, выделенная в вызываемой стороне, может быть спокойно высвобождена в вызывающей вызовом к тому же аллокатору. Причём аллокаторов может быть много.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: Вот вопрос...

Сообщение SLIM » 30.09.2010 (Чт) 6:35

Хакер писал(а):Вызываемая функция не выделяет память, а получает указатель на (заранее выделенный вызывающей стороной) буфер. И пишет туда, если размер подходящий. Соответственно, отвечает за буфер вызывающая сторона.

Да, но я вот говорю что нет гарантии (теоретически) что вызывающая сторона правильно сможет очистить буфер. Вдруг это будет программа на Java, сможет ли она корректно освободить участок, созданный с помощью malloc на C++?
Хакер писал(а):Для любой функции, которая что-то выделяет, создаётся парная функция, которая это что-то уничтожает. CreateXXX/DestroyXXX.

Этот вариант я описал, но немного иначе. Только не парную функцию создавать, а одну функцию по очистке памяти, которая разом все очистит. Просто я представил как было бы программировать если бы на каждую выделяющую внешнюю функцию пришлось бы вызывать дополнительно другую. А если их 100, получается нужно еще 100 для очистки памяти. Много однако
Хакер писал(а):В COM исповедуется концепция аллокатора: есть объект-аллокатор, поддерживающий интерфейс IMalloc. И вызывающая, и вызываемая сторона владеет аллокатором, так что память, выделенная в вызываемой стороне, может быть спокойно высвобождена в вызывающей вызовом к тому же аллокатору. Причём аллокаторов может быть много.

С COM как раз здесь проблем бы не было. COM очень хорошо подумал над управлением памятью. Но у меня не COM, ибо писать этот функционал на COM - тяжкий труд.

Я вот вспомнил концепцию WIN API, а именно функции, которые возвращают указатели на какие-то буфера. Все таки высвобождение перекладывается на вызывающий сторону всегда. Они же не боятся что что-то произойдет не так. Почему? Ведь функции API могут использоваться везде. Почему MS не боится что произойдет неверная очистка памяти.
Хотя, если опять таки вспомнить, для строк мы передаем вызывающей стороне уже готовый буфер, а иногда, с указанием размера того буфера. Тогда проблем не должно возникать. Мы передаем всего лишь указатель на кусочек памяти, и предлагаем его заполнить вызываемой стороне. Вызываемая сторона не работает с памятью вовсе, а просто заполняет буфер. Причем если не вошло - это проблема вызывающей стороны.
Вот кажется одно из решений
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Вот вопрос...

Сообщение Хакер » 30.09.2010 (Чт) 6:39

SLIM писал(а):Да, но я вот говорю что нет гарантии (теоретически) что вызывающая сторона правильно сможет очистить буфер. Вдруг это будет программа на Java, сможет ли она корректно освободить участок, созданный с помощью malloc на C++?

Ну ты трудный фантазёр. У тебя вызывающая сторона на Java или на С++. Уж определись, ибо одновременно быть написанной на обоих языках она не может.


SLIM писал(а):Только не парную функцию создавать, а одну функцию по очистке памяти, которая разом все очистит

Эталон кривизны и дебилизма.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Вот вопрос...

Сообщение Twister » 30.09.2010 (Чт) 10:41

Прежде чем задаваться такими вопросами, стоит поглядеть на то, как это организовано в ОС. А организовано оно двумя способами, которые перечислил Хакер. И это вполне обосновано и логично. Выделять же память на вызываемой стороне можно только в том случае, если сторона вызывающая использует аналогичные методики memory-management'а.

Ну, а по поводу "одной функции, которая разом все очистит", это конечно бред. Как ты представляешь себе её работу? Смотри: у тебя выделено 100 кусков памяти, 50 из них еще в работе, 50 уже не нужны. Тебе нужно отдать свободную память. Как ты это сделаешь?
А я все практикую лечение травами...

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: Вот вопрос...

Сообщение SLIM » 30.09.2010 (Чт) 20:32

Twister писал(а):Ну, а по поводу "одной функции, которая разом все очистит", это конечно бред. Как ты представляешь себе её работу? Смотри: у тебя выделено 100 кусков памяти, 50 из них еще в работе, 50 уже не нужны. Тебе нужно отдать свободную память. Как ты это сделаешь?

В смысле отдать? Освободить?

Ну алгоритм примерно следующий
В библе
1. Заводим глобальный массив указателей, изначально каждому присваиваем NULL
2. Как только какая-то ф-я из библы резервирует память, она передает указатель на нее куда-то во вне - в вызывающую сторону, и копирует указатель в первый свободный элемент того самого массива. Определить следующий свободный можно просто проверкой на NULL.
3. Так, функции все выделяют и выделяют - сколько хотят. Но будет одна единственная функция, реализованная в самой библе, которая пройдется по всему массиву, освободит память по указателям память и опять за' NULL-ит указатели. Такую функцию можно периодически вызывать для подчистки памяти.

По поводу - 50 еще в работе. Суть в следующем, вызывающая сторона должна копировать данные себе, а не использовать указатель, который получила. Тогда конфликта не возникнет. Т.е. - получила вызывающая сторона указатель, скопировала все данные по указателю себе и все, больше указатель не нежен. Правда нужно будет вести учет - сколько памяти на самом деле выделять в вызывающей стороне, так, чтобы вошло все что есть в вернутом указателе.

Twister писал(а):Выделять же память на вызываемой стороне можно только в том случае, если сторона вызывающая использует аналогичные методики memory-management'а.

Вот и я о том же. Поэтому нельзя позволить чтобы память выделялась в вызывающей стороне в принципе. Потому что это библиотека, и не известно где она будет юзаться.
Twister писал(а):Прежде чем задаваться такими вопросами, стоит поглядеть на то, как это организовано в ОС. А организовано оно двумя способами, которые перечислил Хакер.

Я не спорю. Я в предыдущем посте описал один из методов, просто сначала невнимательно прочитал. Но вот по поводу второго пункта Хакера - я такого в ОС не помню.

Ладно, значит так оно и есть.

Было еще пару доп. вопросов. Кто-нибудь ответит?


UPD::
Twister писал(а):Выделять же память на вызываемой стороне можно только в том случае, если сторона вызывающая использует аналогичные методики memory-management'а.


Опа...это где такое написано то? Может наоборот, выделять нельзя в вызывающей стороне а не в вызываемой?
Пишите жизнь на чистовик.....переписать не удастся.....

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Вот вопрос...

Сообщение Хакер » 01.10.2010 (Пт) 2:28

SLIM писал(а):Но вот по поводу второго пункта Хакера - я такого в ОС не помню.

CreateWindow/DestroyWindow
CreateProcess/TerminateProcess
CreateThread/TerminateThread
Ну и т.п.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Re: Вот вопрос...

Сообщение Twister » 01.10.2010 (Пт) 8:16

По поводу - 50 еще в работе. Суть в следующем, вызывающая сторона должна копировать данные себе, а не использовать указатель, который получила. Тогда конфликта не возникнет.
Видать, решение самого первого вопроса в этом топике тебе на ус не намоталось. Напомню: память может освободиться еще до того, как её к себе скопируют. Твоя же функция по очистке это сделает. Да и вообще, что за ересь? Ты так и будешь описывать работу своей библиотеки - "вызывающая сторона должна как можно быстрее скопировать память к себе, так как в любой момент её может уже не быть"? Прежде чем начинать изобретать свой "сборщик мусора" подумай, а зачем он вообще здесь?

Опа...это где такое написано то? Может наоборот, выделять нельзя в вызывающей стороне а не в вызываемой?
Нет, как раз-таки память выделять и освобождать рекомендовано на вызывающей стороне. Я не опечатался. Мало того, я рекомендовал обратить внимание на то, как это реализовано в ОС. Второй пункт ты точно не разбирал, раз вынудил Хакера привести примеры, а теперь я вижу, что и первый не осилил.

Давай посмотрим на GetClassName, к примеру. Второй её параметр - указатель на блок памяти, в котороый ляжет имя класса окна. Т.е. твой код (вызывающая сторона) выделяет память и передаёт указатель на неё в функцию (вызываемая сторона). Функция делает что надо и возвращает тебе управление. Ты делаешь что надо и освобождаешь память.
А я все практикую лечение травами...

SLIM
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1840
Зарегистрирован: 04.04.2008 (Пт) 18:21
Откуда: Краснодар

Re: Вот вопрос...

Сообщение SLIM » 01.10.2010 (Пт) 20:10

Twister писал(а):Видать, решение самого первого вопроса в этом топике тебе на ус не намоталось. Напомню: память может освободиться еще до того, как её к себе скопируют. Твоя же функция по очистке это сделает. Да и вообще, что за ересь? Ты так и будешь описывать работу своей библиотеки - "вызывающая сторона должна как можно быстрее скопировать память к себе, так как в любой момент её может уже не быть"? Прежде чем начинать изобретать свой "сборщик мусора" подумай, а зачем он вообще здесь?

Я не настаиваю делать так как я говорю. Это лишь один из вариантов. Замечания вполне оправданные, и теоретически есть вероятность того что до того как произойдет копирование памяти она будет освобождена. Но очень маленькая. По поводу описания библиотеки тоже согласен. Это выглядит не очень.
Twister писал(а):Нет, как раз-таки память выделять и освобождать рекомендовано на вызывающей стороне. Я не опечатался. Мало того, я рекомендовал обратить внимание на то, как это реализовано в ОС. Второй пункт ты точно не разбирал, раз вынудил Хакера привести примеры, а теперь я вижу, что и первый не осилил.

Это я неверно прочитал. Вызывающий-вызываемая. Попутал что у Хакера что у тебя. Я все прекрасно понимаю.

Как бы я многое из топика здесь прекрасно понимаю, а получается что я вообще даун. Просто недопонял.
Пишите жизнь на чистовик.....переписать не удастся.....

Пред.

Вернуться в Windows-программирование

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

    TopList