Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > объект исчезает после обращения к нему


Автор: ragzovskii 13.4.2010, 18:20
пишу на Visual C++ программу, работающую с СУБД Cache. чтобы позволить С++ работать с объектами из БД, Cache создает классы-проекции, в которых определены типы d_vector, d_obj_vector и так далее. в общем все, что начинается с d_

Controller.h
Код

class Controller
{
public:
    Controller(InterSystems::d_connection);
    ~Controller(void);

    TreeModel* treeModel;
    Database dataBase;
    d_ref<d_obj_vector<Classificator> > cVector;
    d_ref<d_obj_vector<FactData> > fVector;
    d_ref<d_obj_vector<Parameter> > pVector;

    void generate_tree();

    d_ref<Classificator> getClByName(std::string);
    
};


Controller.cpp
Код

Controller::Controller(InterSystems::d_connection conn):dataBase(conn)
{
    treeModel = new TreeModel;
    d_ref<Classificator> classificator;
    d_ref<FactData> factData;
    d_ref<Parameter> parameter;
    cVector = d_obj_vector<Classificator>::create_new(&dataBase);
    fVector = d_obj_vector<FactData>::create_new(&dataBase);
    pVector = d_obj_vector<Parameter>::create_new(&dataBase);
// Далее идет заполнение этих векторов
}

void Controller::generate_tree()
{
    treeModel->generateClTree(cVector);
}

d_ref<Classificator> Controller::getClByName(std::string name)
{
       d_ref<Classificator> tempCls;
    for(int i=0; i!=cVector->size(); i++)
    {
        tempCls = (*cVector)[i];
        if (tempCls->getName()==name) return tempCls;
    }
    return NULL;    
}


Treemode.cpp
Код

void TreeModel::generateClTree(InterSystems::d_ref<d_obj_vector<Classificator>> vector)
{
    QTextCodec::setCodecForTr(QTextCodec::codecForName("cp1251")); // Для функций перевода tr()
    QList<QVariant> rootData;
    rootData << "test";
    rootItem = new TreeItem(rootData);
    for(int i=0; i!=vector->size();i++)
    {
        QList<QVariant> tempData;
//        d_ref<Classificator> tempCls = (*vector)[i];
        std::string s( vector->operator[](i)->getName() );
        QString q(QObject::tr(s.c_str()));
        tempData.append(q);
        rootItem->appendChild(new TreeItem(tempData,rootItem));
    }
}


после вызова функции Controller::generateTree() попытка    вызвать cVector->size() дает access violation.
не хотелось бы каждый раз заполнять этот вектор из БД. не подскажете решение?
заранее спасибо

Автор: mes 13.4.2010, 18:26
Цитата(ragzovskii @  13.4.2010,  17:20 Найти цитируемый пост)
не хотелось бы каждый раз заполнять этот вектор из БД. не подскажете решение?

ну а что есть d_ref  ? судя по Вашему описанию ошибка в нем..

Автор: ragzovskii 13.4.2010, 19:14
если верить http://vista.intersystems.com/csp/docbook/DocBook.UI.Page.cls?KEY=GCPP_using, то:

C++ library comes with a template class, d_ref<>, that encapsulates the behavior of references to proxy classes. An instance of d_ref<T> is a smart pointer to a proxy object of type T. This means that you can
 Call methods of the proxy object using the “->” (pointer) operator.
 Copy one d_ref<> to another. The two d_ref<> instances will point to the same proxy object.
 Pass a d_ref<> as an argument to a proxy method that may change the d_ref<> to point to another proxy object.

Автор: mes 13.4.2010, 20:04
Цитата(ragzovskii @  13.4.2010,  18:14 Найти цитируемый пост)
если верить этому, то:

ну а как дело обстоит у d_ref с деструктором ? 
чтоб проверить предположение можете изменить
Код

void TreeModel::generateClTree(InterSystems::d_ref<d_obj_vector<Classificator>> vector)

на 
Код

void TreeModel::generateClTree(InterSystems::d_ref<d_obj_vector<Classificator> > & vector) // добавлен & 

изменилось ли поведение после исправления ?


Автор: ragzovskii 13.4.2010, 20:17
ничего не изменилось. добавил в .h и .cpp, передаваемое значение оставил прежним. ошибок компиляции нет, access violation есть 

Автор: mes 13.4.2010, 20:25
Цитата(ragzovskii @  13.4.2010,  19:17 Найти цитируемый пост)
access violation 

ну а если закомментируете вызов generateClTree  AV остается ?

Автор: ragzovskii 13.4.2010, 20:34
нет. AV возникает после второго обращения.

например:

Код

void Controller::generate_tree()
{
    d_ref<d_obj_vector<Classificator>> tempVector = d_obj_vector<Classificator>::create_new(&dataBase);
    for(int i=0; i!=cVector->size();i++)
    {
        tempVector->insert(tempVector->end(),d_ref<Classificator>(cVector->operator [](i)));
    }
    treeModel->generateClTree(tempVector);
}


даже после такого использования возникает AV при обращении к cVector в следующей функции.



Автор: jonie 13.4.2010, 21:29
есть подохрение что так cVector->operator [](i) делать не стоит.. возможно в cVector перегружен operator* ?
В общем мое имхо: смотреть stack call стоя на AV ...

Автор: mes 13.4.2010, 21:46
Цитата(ragzovskii @  13.4.2010,  19:34 Найти цитируемый пост)
void Controller::generate_tree()
{
    d_ref<d_obj_vector<Classificator>> tempVector = d_obj_vector<Classificator>::create_new(&dataBase);
    for(int i=0; i!=cVector->size();i++)
    {
        tempVector->insert(tempVector->end(),d_ref<Classificator>(cVector->operator [](i)));
    }
    treeModel->generateClTree(tempVector);
}


а если упростить ?
Код

{

    for(int i=0; i!=cVector->size();i++)
    {
        (*cVector) [i];
    }

    for(int i=0; i!=cVector->size();i++) // AV будет тут ?! 
    {
        (*cVector)[i];
    }
}

и проверьте чему равен cVector в точке 1. и 2.

Автор: ragzovskii 14.4.2010, 07:12
Код немного другой :

Код

    for(int i=0; i!=cVector->size();i++)
    {
        (*cVector)[i];
    }
    for(int i=0; i!=cVector->size();i++) 
    {
        (*cVector)[i];
    }



и AV не появляется, cVector содержит то, что должен

Автор: mes 14.4.2010, 08:46
Цитата(ragzovskii @  14.4.2010,  06:12 Найти цитируемый пост)
Код немного другой :

ах.. да..запарился.. исправил  smile

Цитата(ragzovskii @  14.4.2010,  06:12 Найти цитируемый пост)
и AV не появляется, cVector содержит то, что должен 

интересно.. т.е. AV появляется только при вызове generateClTree ?. 
ну тогда методом научного тыка можете определить  какое из трех использований губит вектор..
smile



Автор: ragzovskii 14.4.2010, 09:10
вектор губит завершение работы функции. он ведет себя как локальная переменная. и я никак не пойму почему

Автор: mes 14.4.2010, 10:10
Цитата(ragzovskii @  14.4.2010,  08:10 Найти цитируемый пост)
вектор губит завершение работы функции. 

ну значит первое предположение о причине в передаче параметров верно.

смущает то, что Вы пробовали уже передавать по ссылке и не изменилось.. 

Автор: ragzovskii 14.4.2010, 18:59
Онотоле вбил немного разума в мою голову и показал мне где я сделал ошибку.

В конструкторе класса, имеющего поле типа Controller я вместо

controller = new Controller(conn);

написал 

Controller controller(conn); 


Автор: kemiisto 14.4.2010, 19:24
No comments. (с) BBC smile 

Понятно, конечно, что если б видеть вес код, гадать на кофейной гуще бы не пришлось. Но всё равно доставило, спасибо.

ragzovskii, ты не пробовал использовать http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6? С ними такого не было. Я так себя приучил: добавил новый данное-член smile к классу -> добавил инициализатор в списочек в конструктор, конструктор копирования (если есть), поправил перегруженные операторы = и т.п. Постоянно пытаюсь, чтоб это дело было согласовано.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)