Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание глобального хэндла с помощью локального 
V
    Опции темы
vdm
Дата 1.3.2010, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Код

HANDLE hThreadEvent;

main() {
HANDLE hTh = CreateEvent(0,0,0,0);
hThreadEvent = hTh;
CloseHandle(vTh);
vTh = NULL;
SetEvent(hThreadEvent);
WaitForSingleObject(hThreadEvent, INFINITE);
}


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

П.с. чтобы невозникло вопросов - это тупо явный пример самой идеи. Важна инфо в правильности действий а не логики smile

Это сообщение отредактировал(а) vdm - 1.3.2010, 17:57
PM MAIL   Вверх
GremlinProg
Дата 1.3.2010, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vdm @  1.3.2010,  19:55 Найти цитируемый пост)
локальный хэндл после копирования его значения освобождать ненадо




--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
vdm
Дата 2.3.2010, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Цитата(GremlinProg @ 1.3.2010,  19:31)
Цитата(vdm @  1.3.2010,  19:55 Найти цитируемый пост)
локальный хэндл после копирования его значения освобождать ненадо

За ним следует вопрос, а не получу ли утечку по памяти таким образом создпвая хэндлы?

Привожу пример. Если в Debug mode установить 2 break point'a 1. перед выполнением первого цикла for() и на нём посмотреть в Task manager выделенную память и второй на return; - то здесь памяти будет больше чем на первой точке break point'a. Почему? Утечка?

Код

#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <vector>
using std::vector;

vector<HANDLE> VH;
void fn()
{
    HANDLE vg = CreateEvent(0,0,0,0);
    VH.push_back(vg);
    
}
int _tmain(int argc, _TCHAR* argv[])
{
    for(int i=0;i<999999;i++)
        fn();
    for(int i=0;i<999999;i++) {
        CloseHandle(VH.at(i));
        VH.at(i)=NULL;
    }
    VH.clear();
    vector<HANDLE>().swap(VH);

    return 0;
}

PM MAIL   Вверх
Earnest
Дата 2.3.2010, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Цитата(vdm @  2.3.2010,  14:30 Найти цитируемый пост)
За ним следует вопрос, а не получу ли утечку по памяти таким образом создпвая хэндлы?

Хэндл ты создаешь только один раз, а потом копируешь его значение.
Поставь вместо "хэндл" слово "указатель" и подумай, надо ли освобождать "локальный" указатель после копирования его значения в глобальную переменную. Смысл один и тот же.
Цитата(vdm @  2.3.2010,  14:30 Найти цитируемый пост)
Привожу пример.

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



--------------------
...
PM   Вверх
vdm
Дата 2.3.2010, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Цитата

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


День добрый, Earnest.
Нет ненадо. Спасибо за дополнительное разъяснение. Немного выше GremlinProg уже дал ответ на этот вопрос.

Это сообщение отредактировал(а) vdm - 2.3.2010, 16:32
PM MAIL   Вверх
xvr
Дата 2.3.2010, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(vdm @ 1.3.2010,  17:55)
Код

HANDLE hThreadEvent;

main() {
HANDLE hTh = CreateEvent(0,0,0,0);
hThreadEvent = hTh;
CloseHandle(vTh);
vTh = NULL;
SetEvent(hThreadEvent);
WaitForSingleObject(hThreadEvent, INFINITE);
}


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

В твоем примере никаких 'локальных хэндлов' не создается. Для создания хэндла недостаточно присвоить его из одной переменной в другую, это создаст не 'копию хэндла', а отдублирует один и тот же хэндл в 2 перемнные. Т.ч. в твоем примере SetEvent в 8й строке даст ошибку, т.к. его хэндл был закрыт в 6й строке.
Для создания дубликатов хэндлов служит функция DuplicateHandle

Цитата

Так правильно или локальный хэндл после копирования его значения освобождать ненадо?

Все хэндлы, созданные любым путем (и через Create*, и через DuplicateHandle), надо закрывать через CloseHandle


PM MAIL   Вверх
vdm
Дата 3.3.2010, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



xvr, а есть существенная разница между дублированием локального указателя через копирование его содержимого на другой (глобальный) указатель то есть (HANDLE)  и копированием через ф-цию DublicateHandle? По мне особой разницы нет...

При чём DublicateHanle не уместен, если собераюсь HANDLE'ы хранить в куче как в 3 посте.

Это сообщение отредактировал(а) vdm - 3.3.2010, 09:58
PM MAIL   Вверх
Earnest
Дата 3.3.2010, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Конечно, есть, и весьма существенная. DublicateHandle создает НОВЫЙ хэндл на тот же объект ядра, поэтому его и надо закрывать отдельно. А присваивание просто копирует значение. В этом смысле хэндл ничем не отличается от других переменных. Ты копируешь хэндл (и любую другую переменную) каждый раз, когда передаешь его куда-нибудь по значению. 


--------------------
...
PM   Вверх
vdm
Дата 3.3.2010, 10:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



Утро доброе Earnest, я к тому что DublicateHandle по теме не совсем уместен, так как нужна передача с локального хранилищя в глобальное. Что успешно и без последствий можно реализовать на примере 3 поста. smile

Это сообщение отредактировал(а) vdm - 3.3.2010, 10:13
PM MAIL   Вверх
GremlinProg
Дата 3.3.2010, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



Цитата(vdm @  3.3.2010,  12:13 Найти цитируемый пост)
я к тому что DublicateHandle по теме не совсем уместен, так как нужна передача с локального хранилищя в глобальное. Что успешно и без последствий можно реализовать на примере 3 поста

vdm, открой диспетчер задач на вкладке процессы,
далее: Вид -> Выбрать столбцы...
включи "Счетчик дескрипторов"

а теперь смотри на его изменение в обоих примерах

DublicateHandle тут указан к тому, чтобы ты не путался в понятиях "локальный дескриптор" и "локальная переменная", а в примерах - конечно, DublicateHandle не требуется


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
xvr
Дата 3.3.2010, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(vdm @ 3.3.2010,  09:27)
xvr, а есть существенная разница между дублированием локального указателя через копирование его содержимого на другой (глобальный) указатель то есть (HANDLE)  и копированием через ф-цию DublicateHandle? По мне особой разницы нет...

Разница есть, но давай вернемся к первоисточнику - тема называется Создание глобального хэндла с помощью локального. Так вот, при копировании хэндла из локальной переменной в глобальную никакой 'глобальный хэндл' НЕ СОЗДАЕТСЯ. И вообще никакой хэндл не создается. Как исходно был один единственный хэндл, так он и остается одним единственным хэндлом (тем же самым). Просто теперь этот хэндл лежит в 2 ПЕРЕМЕННЫХ.

Цитата

При чём DublicateHanle не уместен, если собераюсь HANDLE'ы хранить в куче как в 3 посте.
Да, в твоем примере он неуместен, но он делает именно то, что написанно в заголовке темы. Другой вопрос, что в заголовке написанно не то, что реально нужно сделать  smile 


Это сообщение отредактировал(а) xvr - 3.3.2010, 13:25
PM MAIL   Вверх
vdm
Дата 3.3.2010, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 236
Регистрация: 16.10.2007

Репутация: нет
Всего: нет



 xvr, smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.