Vector при добавлении нового элемента удаляет старый

Тема в разделе "Общие вопросы по С и С++", создана пользователем Monarh, 14 фев 2009.

  1. Monarh

    Monarh Active Member

    Регистрация:
    14 фев 2009
    Сообщения:
    34
    Симпатии:
    0
    Не могу разобраться зачем он так поступает :(

    Имеется 2 класса:

    Код (Text):
    class Cls_A
    {
    char* CA_Format;
    void* VPtr_Array;
    Cls_A();
    void* Allocation( string& Format ); // В соответствии с содержимым строки Format выделяет память под CA_Format и VPtr_Array;
    void DeAllocation();
    ~Cls_A();
    }

    Cls_A::Cls_A()
    {
    CA_Format = NULL;
    VPtr_Array = NULL;
    }

    void Cls_A::DeAllocation()
    {
    if( CA_Dimensions_Info != NULL )
    {
    delete[] CA_Dimensions_Info;
    CA_Dimensions_Info = NULL;
    }

    if( VPtr_Array != NULL )
    {
    delete[] (char*)VPtr_Array;
    VPtr_Array = NULL;
    }
    }

    Cls_A::~Cls_A()
    {
    DeAllocation();
    }
    Код (Text):
    class Cls_B
    {
    ...
    vector<Cls_A> VecCls_A;
    void* Allocation();
    ...
    }

    void* Cls_B::Allocation()
    {
    ...
    Cls_A* ClsPtr_A = NULL;
    ClsPtr_A = new Cls_A;
    ...

    void* VPtr_Array;
    (1) VPtr_Array = ClsPtr_A -> Allocation( Str_Format );

    // Вставляем вновь созданный Массив в найденную позицию Place_for_Insert.
    (2) VecCls_A.insert( Place_for_Insert( VPtr_Array ), (*ClsPtr_A) );
    ...
    }
    При добавлении, первый раз, класса Cls_A в функции Cls_B::Allocation()
    на стадии (1) выделяется память нормально.
    на стадии (2) добавляется в вектор нормально.

    При добавлении, второй раз, класса Cls_A в функции Cls_B::Allocation()
    на стадии (1) выделяется память нормально.
    на стадии (2) программа заползает в деструктор первого объекта и всю память чистит и только после этого, со спокойной душой, добавляет второй объект.
    Хотя первый объект почищен vector.size() == 2 и вроде как указатели указывают на теже адреса, но по тем же адресам уже совсем не то, что надо.
    И на последующем шаге при обращении к первому объекту программа завершает работу с ошибкой.

    Подскажите пожалуйста что не так делаю и как надо.
    Заранее всем большое спасибо !!!
     
  2. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    По этим обрывкам кода ничего понять невозможно
     
  3. Monarh

    Monarh Active Member

    Регистрация:
    14 фев 2009
    Сообщения:
    34
    Симпатии:
    0
    Я уже вроде разобрался.

    Это происходит из-за того, что vector при добавлении нового элемента удаляет все имеющиеся, предварительно создав их копии.
    То есть, в моём примере, поскольку, VecCls_A - это вектор объектов класса Cls_A, то при добавлении нового элемента он создаёт копии
    каждого объекта и затем вызывает деструктор каждого из имеющихся в векторе объектов, чтобы затем их заменить созданными копиями.
    А поскольку в объекте класса Cls_A два указателя, то при копировании копируются только указатели, в то время как при удалении объекта
    удаляются сами массивы на которые указывают эти указатели.

    Выхода, как минимум, два:
    1) написать конструктор копирования, но в моём случае он мне без надобности.
    2) переопределить вектор VecCls_A, как вектор указателей на объекты класса.

    Хотел сделать вектор VecCls_A, как вектор ссылок на объекты класса, но похоже так нельзя.
    Если можно подскажите как.
    Я так понял ссылки при определении должны сразу быть проинициализированы и потому нельзя определить вектор ссылок ???

    Если что-то в моих предположения неверно, то поправьте.
    Заранее всем большое спасибо.
     
  4. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Не совсем так. Вектор хранит свои элементы в непрерывной области памяти. Если при добавлении элемента не хватает выделенной памяти, то вектор осуществляет копирование элементов в бОльшую область память. Управлять размером области памяти можно при помощи метода reserve()
    Хорошим тоном программирования для объектов, содержащих выделенную динамическую память, является или реализация пары оператор присваивания + конструктор копирования или их закрытие
     
  5. Monarh

    Monarh Active Member

    Регистрация:
    14 фев 2009
    Сообщения:
    34
    Симпатии:
    0
    Можно, пожалуйста по-подробнее про закрытие.

    И у меня остался вопрос про вектор ссылок.
    Можно ли это организовать, то есть определить vector<Cls_A&>, или нет ?
     
  6. European

    Регистрация:
    4 сен 2006
    Сообщения:
    2.580
    Симпатии:
    0
    Нет
    Конструктор копирования и оператор присваивания объявляются как private и не реализуются
     
  7. Monarh

    Monarh Active Member

    Регистрация:
    14 фев 2009
    Сообщения:
    34
    Симпатии:
    0
    Теперь всё встало на свои места :)
    Спасибо большое !!!
     
Загрузка...

Поделиться этой страницей