как сделать так, чтобы при создании указателя на пару std::pair<int,someClass*>*, предварительно получив указатель на someClass через new, в дальнейшем при обращении извне (совсем из другого класса) к someClass* через second, этот someClass* не терялся? я так подозреваю, все дело в том, что при создании someClass* через new, после выхода из этого метода, где я его создаю, указатель на него теряется. как это предотвратить? благодарю за наставление на путь истинный. ps: если вместо std::pair<int,someClass*>* юзать std::pair<int,someClass*> то все ок.
varnie [off] До Штирлица не дошла шифровка из центра. Он прочитал ее еще раз. Опять не дошла. [/off] Что именно теряется? Указатель? Значение указателя? Объект, на который он указывает? Что именно значит "теряется"? Недоступность? Некорректность? Приведи фрагмент исходника, что ли...
есть следующее: Код (Text): typedef std::pair<int, myDataClass*> myDataClassEntry; typedef std::map<std::string, myDataClassEntry*> dataClassEntries; typedef std::map<std::string, myDataClassEntry*>::value_type valType; class myBuggyClass { public: //.. bool addInfo() const; const myDataClassEntry *getData(const std::string &name) const; private: dataClassEntries data; }; bool myBuggyClass::addInfo() const { //.. //получили ID int ID = 10; //не суть важно //получили pcurData myDataClass *pCurData = new myDataClass(); //не суть важно myDataClassEntry test = std::make_pair(id,pCurData); myDataClassEntry *pTest = &test; data.insert( valType(name, pTest ) ); } const myDataClassEntry *myBuggyClass::getData(const std::string &name) const { // такие данные есть? dataClassEntries::const_iterator it = data.find(name); if ( it != data.end() ) return it->second; //нету return NULL; } //------------------- далее есть другой класс и в нем в одном из методов нужно получить доступ к определенным myDataClassEntry, хранящимся в приватной переменнной data вышерасписанного класса myBuggyClass. Код (Text): void anotherClass::getData() const { static const myDataClassEntry *entry curBuggyClass->getData("BACKGROUND"); if (!entry->second) { printf("no such data!\n"); ::exit(-1); } else { //далее идет логика программы, если все ок } } если я определяю dataClassEntries и myDataClassEntry как выше (c использованием myDataCLass*), то почему-то в этом методе постоянно в imgBackground->second пусто (выводится "no such data" и прога звершает свою работу), а если же мои данные имеют вид typedef std::pair<int, myDataCLass> myDataClassEntry; typedef std::map<std::string, myDataClassEntry> dataClassEntries; typedef std::map<std::string, myDataClassEntry>::value_type valType; и все переписано соответствующе, то код идет на ура, и в imgBackground.second всегда правильные данные и прога далее исполняется. вот и не пойму, почему так и где я напортачил.
а напортачил вот здесь: Код (Text): bool myBuggyClass::addInfo() const { //.. //получили ID int ID = 10; //не суть важно //получили pcurData myDataClass *pCurData = new myDataClass(); //не суть важно myDataClassEntry test = std::make_pair(id,pCurData); myDataClassEntry *pTest = &test; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ data.insert( valType(name, pTest ) ); } У тебя создается автоматический объект. Берется его адрес. Запихивается в контейнер. Затем addInfo завершается. Объект уничтожается, ибо автоматический. Указатель остается. Указывает в космос. Во втором случае в контейнере лежат не указатели, а сами объекты. Поэтому при вызове insert объект, а не указатель копируется в контейнер. Если хочешь хранить указатели тогда придется написать что-то вроде: Код (Text): myDataClass *pCurData = new myDataClass(); myDataClassEntry *pTest = new myDataClassEntry(id, pCurData); data.insert( valType(name, pTest ) ); и позаботиться об освобождении после - иначе утечка памяти. Проверять же указатели в С++ - дохлый номер, реализация не обязана заботится об его корректности, это тебе не Java.
Ustus, спасибо за прояснение ситуации! я кстати так сразу и подумал, что дело в этом автоматическом объекте, но почему-то не был уверен. воспользовался вашим предложенным решением - заработало!! и без всяких новых классов обошелся еще вопрос - как мне быть уверенным, что при уничтожении объекта, на который указывает мой pTest произойдет корректное освобождение занятой им памяти? достаточно ли будет того, что у меня в деструкторе этого класса будет освобождение памяти через delete ? я это почему спрашиваю - по логике моей программы, удаление этого класса должно выполняться фактически только при завершении проги. как мне быть, положиться на средства си++ (деструкторы) для соотв. класса, или же еще что-то можно предпринять? у меня в деструкторе этого класса стоит data.clear(); data = NULL; этого хватит или нет?
Насколько я смог понять, тебя интересует, освободится ли память при очищении map? Нет. Освобождается лишь выделенная под элементы std::pair. Для освобождения указателей myDataClass* нужно освобождать их самому: Код (Text): for(dataClassEntries::iterator iter = data.begin(); iter != data.end(); iter++) delete iter->second; data.clear();
да, это и имел ввиду. спасибо за помощь. осталось понять, будет ли такого удаления достаточно, если я эту "очистку памяти" data размещу в деструкторе класса, в данных которого эта data и лежит, или же есть более правильное решение?
вас понял. да читал я Страуструпа и еще много чего, просто че-то заклинило и все. ну, теперь расклинило и все встало на свои места.