Как stl контейнеры становятся удаленными?

Логика выглядела бы следующим образом с использованием синтаксиса ANSI / ISO:

where (extract(day from current_date) = 16 and
       extract(month from datecol) = extract(month from current_date) and extract(year from datecol) = extract(year from current_date)
      ) or
      (extract(day from current_date) = 4 and
       extract(month from datecol) = extract(month from current_date - interval '1 month') and extract(year from datecol) = extract(year from current_date - interval '1 month')
      )

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

6
задан Will Dean 20 December 2008 в 08:10
поделиться

12 ответов

Контейнер STL указателя НЕ вымоется, данные указали. Это только очистит пространство, содержащее указатель. Если Вы хотите, чтобы вектор очистил данные указателя, необходимо использовать некоторую реализацию интеллектуального указателя:

{
    std::vector<SomeClass*> v1;
    v1.push_back(new SomeClass());

    std::vector<boost::shared_ptr<SomeClass> > v2;
    boost::shared_ptr<SomeClass> obj(new SomeClass);
    v2.push_back(obj);
}

Когда тот объем закончится, оба вектора освободят свои внутренние массивы. v1 пропустит SomeClass, который был создан, так как только указатель на него находится в массиве. v2 не пропустит данных.

19
ответ дан 8 December 2019 в 02:41
поделиться

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

Указатели обрабатываются тот же путь.
Вещью являются указатели, данные POD. Конструктор копии для указателя должен только скопировать адрес, и данные POD не имеют никакого деструктора. Если Вы хотите, чтобы контейнер управлял указателем, Вы должны:

  • Используйте контейнер интеллектуальных указателей. (например, совместно использованный указатель).
  • Используйте повышение ptr контейнер.

Я предпочитаю контейнер указателя:
Контейнеры указателя совпадают с контейнерами STL кроме Вас помещенные указатели в них, но контейнер затем берет владение объекта точки указателя в и таким образом освободит объект (обычно вызовом, удаляют), когда контейнер уничтожается.

Когда Вы получаете доступ к членам ptr контейнера, они возвращаются через ссылку, таким образом, они ведут себя точно так же, как стандартный контейнер для использования в стандартных алгоритмах.

int main()
{
    boost::ptr_vector<int>    data;

    data.push_back(new int(5));
    data.push_back(new int(6));

    std::cout << data[0] << "\n";  // Prints 5.
    std::cout << data[1] << "\n";  // Prints 6.


}   // data deallocated.
    // This will also de-allocate all pointers that it contains.
    // by calling delete on the pointers. Therefore this will not leak.

Нужно также указать, что интеллектуальные указатели в контейнере являются допустимой альтернативой, к сожалению, станд.:: auto_ptr <> не является допустимым выбором интеллектуального указателя для этой ситуации.

Это вызвано тем, что контейнеры STL предполагают, что объекты, которые они содержат, copyable, к сожалению, станд.:: auto_ptr <> не copyable в традиционном смысле, поскольку он уничтожает исходное значение на копии, и таким образом источник копии не может быть константой.

0
ответ дан 8 December 2019 в 02:41
поделиться

Отвечать на Ваш первый вопрос:

Нет ничего специального о классах STL (я надеюсь). Они функционируют точно как другие шаблонные классы. Таким образом они автоматически не уничтожаются, если выделено на "куче", потому что C++ не имеет никакой сборки "мусора" на них (если Вы не говорите это с некоторым воображением autoptr бизнес или что-то). При выделении его на стеке (без нового), этим будет, скорее всего, управлять C++ автоматически.

Для Вашего второго вопроса вот очень простой класс ArrayOfTen для демонстрации основ типичного управления памятью в C++:

/* Holds ten Objects. */
class ArrayOfTen {
    public:
        ArrayOfTen() {
            m_data = new Object[10];
        }

        ~ArrayOfTen() {
            delete[] m_data;
        }

        Object &operator[](int index) {
            /* TODO Range checking */
            return m_data[index];
        }

    private:
        Object *m_data;

        ArrayOfTen &operator=(const ArrayOfTen &) { }
};

ArrayOfTen myArray;
myArray[0] = Object("hello world"); // bleh

В основном класс ArrayOfTen сохраняет внутренний массив десяти Объектных элементов на "куче". Когда новый [] назван в конструкторе, место для десяти Объектов выделено на "куче", и создаются десять Объектов. Simiarly, когда удаляют [], называют в деструкторе, в десяти Объектах вскрывают противоречия, и затем память, ранее выделенная, освобождена.

Для большинства (все?) типы STL, изменение размеров сделано негласно, чтобы удостовериться, что существует достаточно набора памяти в стороне для установки элементам. Вышеупомянутый класс только поддерживает массивы десяти Объектов. Это - в основном очень ограничивающее определение типа Объекта [10].

0
ответ дан 8 December 2019 в 02:41
поделиться

Как с любым другим объектом в "куче", это должно быть уничтожено вручную (с, удаляют).

0
ответ дан 8 December 2019 в 02:41
поделиться

Удалить элементы указало, я записал простой функтор:

template<typename T>
struct Delete {
    void operator()( T* p ) const { delete p; }
};

std::vector< MyType > v;
// ....
std::for_each( v.begin(), v.end(), Delete<MyType>() );

Но Вы должны нейтрализация на общих указателях, когда содержание вектора должно быть... ehm... совместно использовано. Да.

0
ответ дан 8 December 2019 в 02:41
поделиться

При хранении указателей в контейнерных классах STL, необходимо вручную удалить их, прежде чем объект будет уничтожен. Это может быть сделано цикличным выполнением через целый контейнер и удаляющий каждый объект, или при помощи некоторого класса интеллектуального указателя. Однако не используйте auto_ptr, поскольку тот просто не работает с контейнерами вообще.

Хороший побочный эффект этого состоит в том, что можно сохранить несколько контейнеров указателей в программе, но только владеть теми объектами одним из тех контейнеров, и только необходимо очистить тот один контейнер.

Самый легкий способ удалить указатели состоял бы в том, чтобы сделать:

for (ContainerType::iterator it(container.begin()); it != container.end(); ++it)
{
    delete (*it);
}
2
ответ дан 8 December 2019 в 02:41
поделиться

Если у Вас есть a vector<T*>, Ваш код должен удалить те указатели прежде delete'ing вектор: иначе та память пропущена.

Знайте, что C++ не делает сборки "мусора", вот пример того, почему (извинения за синтаксические ошибки, это было некоторое время, так как я записал C++):

typedef vector<T*> vt;
⋮
vt *vt1 = new vt, *vt2 = new vt;
T* t = new T;
vt1.push_back(t);
vt2.push_back(t);
⋮
delete vt1;

Последняя строка (delete vt1;) ясно не должен удалять указатель, который это содержит; в конце концов, это находится также в vt2. Таким образом, это не делает. И ни один не будет удаление vt2.

(Если Вы хотите тип вектора, который удаляет указатели на, уничтожают, такой тип может, конечно, быть записан. Вероятно, был. Но остерегайтесь delete'ing указателей, из которых кто-то еще все еще держит копию.)

5
ответ дан 8 December 2019 в 02:41
поделиться

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

3
ответ дан 8 December 2019 в 02:41
поделиться

Используйте или интеллектуальные указатели в векторе или используйте ptr_vector повышения. Это автоматически освободит выделенные объекты в нем. Существуют также карты, наборы, и т.д.

http://www.boost.org/doc/libs/1_37_0/libs/ptr_container/doc/ptr_vector.html и основной сайт: http://www.boost.org/doc/libs/1_37_0/libs/ptr_container/doc/ptr_container.html

2
ответ дан 8 December 2019 в 02:41
поделиться

Это - своего рода неправильное употребление. Вектор, как с большинством контейнеров STL, состоит из 2 логических частей.

  1. векторный экземпляр
  2. фактическая реализация основного массива

В то время как настраивающийся, № 2 почти всегда живет на "куче". № 1 однако может жить или на стеке или на "куче", это просто зависит от того, как это выделяется. Например,

void foo() { 
  vector<int> v;
  v.push_back(42);
}

В этом случае часть № 1 живет на стеке.

Теперь, как № 2 становится уничтоженным? Когда первая часть вектора будет уничтожена, она уничтожит вторую часть также. Это сделано путем удаления основного массива в деструкторе векторного класса.

3
ответ дан 8 December 2019 в 02:41
поделиться

Контейнеры STL похожи на любые другие объекты, если вы создаете один экземпляр, он создается в стеке:

std::vector<int> vec(10);

Как и любая другая переменная стека, он только живет в области действия функции, в которой он определен, и не требует удаления вручную. Деструктор контейнеров STL вызовет деструктор всех элементов в контейнере.

Хранение указателей в контейнере - непростая задача. Поскольку указатели не имеют деструкторов, я бы сказал, что вы никогда не захотите помещать необработанные указатели в контейнер STL. Сделать это безопасным способом будет очень сложно, вам придется засорять свой код блоками try {} finally {}, чтобы гарантировать, что содержащиеся указатели всегда освобождаются.

Итак, что вы должны помещать в контейнеры вместо необработанные указатели? +1 jmucchiello за воспитание boost :: shared_ptr. boost :: shared_ptr безопасно использовать в контейнерах STL (в отличие от std :: auto_ptr). В нем используется простой механизм подсчета ссылок, и он безопасен для структур данных, не содержащих циклов.

Что вам понадобится для структур данных, содержащих циклы? В этом случае вы, вероятно, захотите перейти к сборке мусора, что по сути означает использование другого языка, такого как Java. Но это другое обсуждение. ;)

d придется засорять ваш код блоками try {} finally {}, чтобы гарантировать, что содержащиеся указатели всегда освобождаются.

Итак, что вы должны поместить в контейнеры вместо необработанных указателей? +1 jmucchiello за воспитание boost :: shared_ptr. boost :: shared_ptr безопасно использовать в контейнерах STL (в отличие от std :: auto_ptr). Он использует простой механизм подсчета ссылок и безопасен для структур данных, не содержащих циклов.

Что вам понадобится для структур данных, содержащих циклы? В этом случае вы, вероятно, захотите перейти к сборке мусора, что по сути означает использование другого языка, такого как Java. Но это другое обсуждение. ;)

d придется засорять ваш код блоками try {} finally {}, чтобы гарантировать, что содержащиеся указатели всегда освобождаются.

Итак, что вы должны поместить в контейнеры вместо необработанных указателей? +1 jmucchiello за воспитание boost :: shared_ptr. boost :: shared_ptr безопасно использовать в контейнерах STL (в отличие от std :: auto_ptr). Он использует простой механизм подсчета ссылок и безопасен для структур данных, не содержащих циклов.

Что вам понадобится для структур данных, содержащих циклы? В этом случае вы, вероятно, захотите перейти к сборке мусора, что по сути означает использование другого языка, такого как Java. Но это другое обсуждение. ;)

shared_ptr безопасно использовать в контейнерах STL (в отличие от std :: auto_ptr). В нем используется простой механизм подсчета ссылок, и он безопасен для структур данных, не содержащих циклов.

Что вам понадобится для структур данных, содержащих циклы? В этом случае вы, вероятно, захотите перейти к сборке мусора, что по сути означает использование другого языка, такого как Java. Но это другое обсуждение. ;)

shared_ptr безопасно использовать в контейнерах STL (в отличие от std :: auto_ptr). Он использует простой механизм подсчета ссылок и безопасен для структур данных, не содержащих циклов.

Что вам понадобится для структур данных, содержащих циклы? В этом случае вы, вероятно, захотите перейти к сборке мусора, что по сути означает использование другого языка, такого как Java. Но это другое обсуждение. ;)

0
ответ дан 8 December 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: