Russian Qt Forum
Ноябрь 24, 2024, 02:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Мелкая проблема с ключом-указателем  (Прочитано 4220 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Март 18, 2011, 22:26 »

Добрый вечер

Использую std::map <myPtr *, myData>, т.е. ключ указатель. Это имеет маленький, но противный минус - невоспроизводимость. То есть при новом запуске myPtr могут встать в памяти не так как при предыдущем. Хотя когда я итерирую  контейнер, результат тот же, уходит много времени на отладку - ведь теперь воспроизвести ситуацию не получается. Толкаю - вылетела, еще раз - работает, или наоборот  Смеющийся

Пришлось поместить указатели в вектора а ключи заменить на индексы (в этих векторах). 
Записан
ufna
Гость
« Ответ #1 : Март 18, 2011, 23:49 »

Добрый вечер

А вопрос сабжа то "кто виноват"? Улыбающийся
Записан
serg_hd
Хакер
*****
Offline Offline

Сообщений: 668



Просмотр профиля
« Ответ #2 : Март 19, 2011, 01:32 »

Человек, видимо, просто делится опытом. Непонятен момент:

То есть при новом запуске myPtr могут встать в памяти не так как при предыдущем.
Что значит "при новом запуске"? Создание объекта в куче? Если да, то выделение будет из другого участка памяти, это же вполне законно. Или в чём подвох? Интересно просто, чтоб не повторить этого.
Записан

kubuntu/Win7/x64/NetBeans
Akon
Гость
« Ответ #3 : Март 19, 2011, 09:05 »

Используй hash-контейнер, если такое поведение тебя не устраивает.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Март 19, 2011, 12:49 »

Человек, видимо, просто делится опытом. Непонятен момент:

То есть при новом запуске myPtr могут встать в памяти не так как при предыдущем.
Что значит "при новом запуске"? Создание объекта в куче? Если да, то выделение будет из другого участка памяти, это же вполне законно. Или в чём подвох? Интересно просто, чтоб не повторить этого.
Пример

Код
C++ (Qt)
QMap <MyClass *, int> theMap;  
MyClass * p0 = new MyClass();
theMap[p0] = 0;
...
MyClass * p1 = new MyClass();
theMap[p1] = 1;
...
MyClass * p2 = new MyClass();
theMap[p2] = 2;
...
 
Никто не обещает что p0 < p1 < p2 или что вообще они будут в каком-то фиксированном порядке - зависит от того что с кучей на данный момент. Поэтому напр. theMap.begin() может вернуть итератор на p0 или p1 или p2 (как фишка ляжет) каждый раз когда указатели снова созданы и theMap заполнена. Хотя порядок итерации в большинстве случаев не имеет значения, мне лично это неудобно для ловли багов/отладки.

Используй hash-контейнер, если такое поведение тебя не устраивает.
Насколько мне известно, (Q)hash вообще не обещает что элементы будут итерироваться в каком-то порядке, он просто "arbitrary" (произвольный)
Записан
Akon
Гость
« Ответ #5 : Март 19, 2011, 13:22 »

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

Как вариант с указателями - можешь сделать MyClass::operator new(), который будет использовать твой распределитеть, который будет распределять память строго упорядоченно (p1 < p2 < p3 ...).
« Последнее редактирование: Март 19, 2011, 13:28 от Akon » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Март 19, 2011, 13:52 »

Как вариант с указателями - можешь сделать MyClass::operator new(), который будет использовать твой распределитеть, который будет распределять память строго упорядоченно (p1 < p2 < p3 ...).
Ну это легко для фиксированного (небольшого) числа экземпляров, а иначе я не знаю как. Да и указатель может быть совсем "не на мой класс" и/или лезть в этот класс не резон. В общем, хотя и интересно, но сложновато  Улыбающийся
Записан
Waryable
Гость
« Ответ #7 : Март 19, 2011, 15:35 »

Так то интересно зачем реализованно именно так. Улыбающийся
Есть предложение(псевдокод):
Код
C++ (Qt)
struct
{
       int Key;
       TBaseClass* MyClass;
}TStruct;
 
 
QMap<TStruct.key, TStruct>
 
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Март 20, 2011, 10:33 »

Так то интересно зачем реализованно именно так. Улыбающийся
Есть предложение(псевдокод):
Код
C++ (Qt)
struct
{
       int Key;
       TBaseClass* MyClass;
}TStruct;
 
 
QMap<TStruct.key, TStruct>
 
Какой Вы быстрый  Улыбающийся Нужно зарядить операторы < и == для TStruct (ну и конструктор для приличия). Плюс Key надо как-то вычислять/наращивать. Я сделал так

Код
C++ (Qt)
typedef size_t TMapID;
QMap <TMapID, MyValue *> theMap;
QVector <MyClass *> theVec;
..
MyClass * p0 = new MyClass();
theMap[theVec.size()] = new MyValue();
theVec.push_back(p0);
 
Это впрочем имеет тот минус что все использующие theMap должны иметь доступ и к theVec.

Записан
Akon
Гость
« Ответ #9 : Март 20, 2011, 21:01 »

Еще вариант - обертка для MyClass по типу смарт-поинтера, т.е. реализующая operator->() и все необходимое. В обертке есть поле-ключ (например, тупо инкрементальный счетчик). Само-собой, для обертки есть все то, что нужно QMap (operator>() и т.д.). Различия в коде с оберткой и без минимальны.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.197 секунд. Запросов: 22.