изменение размера вектора - портативный способ обнаружения - PullRequest
0 голосов
/ 02 марта 2009

У меня есть вектор, который я загружаю с известным количеством элементов (N).

Обработка динамически создает новые элементы, которые добавляются к вектору.

Я ожидаю, что будет создано около 2 * N дополнительных элементов, поэтому я изменяю размер вектора до 3 * N.

Если дополнительные элементы превышают это значение, я хотел бы, чтобы программа прервалась, а не динамическое расширение вектора.

Есть ли способ обнаружить это, переносимый между AIX / TRU64 / Linux?

Ответы [ 5 ]

3 голосов
/ 02 марта 2009

Почему вы используете вектор? Весь смысл вектора в том, чтобы динамически расширяться при необходимости.

Вместо создания класса для делегирования вектору, просто создайте класс для делегирования в простой массив. Попросите ваш push_back проверить размер и отменить при необходимости.

3 голосов
/ 02 марта 2009

Обнаружить что? Будет ли изменен вектор? Было ли это?

Единственный реальный способ добиться этого - обеспечить проверку функциональности либо в пользовательском распределителе, либо в функции, которая добавляет элементы в вектор.

* 1005 например *

template<class T> 
void add_element(std::vector<T>& container, T const& v)
{
  if (container.capacity()+1 >= 3*N)
  {
    // terminate/exception/whatever
  }

 container.push_back(v);
}
2 голосов
/ 02 марта 2009

Стандартные классы используют распределитель, вызываемый каждый раз, когда вы вставляете элемент. Вы можете написать новый распределитель, унаследованный от std :: alocator, и добавить все виды проверок / трассировок, которые вам нужны.

(я делал это раньше, но мне потребовалось некоторое время, чтобы создать рабочий код.)

2 голосов
/ 02 марта 2009

Если вы знаете размер во время компиляции, возможно, лучше использовать std :: tr1 :: array (или boost :: array ). Он сохраняет фиксированный размер и проверяет доступ как std :: vector.

Если, однако, вы знаете это только во время выполнения, как уже было сказано другими, вы должны инкапсулировать свой вектор в классе с помощью специальных функций, которые будут проверять необходимые условия (например, с помощью утверждений).

В этом последнем подходе я бы предложил, если вы знаете максимальный размер при создании вектора, зарезервировать (std :: vector :: reserve ()) максимальный размер вектора в конструкторе инкапсулирующего класса (или функция инициализации). Таким образом, больше не будет манипуляций с памятью самим вектором (только если конструктор / деструктор векторных элементов выполняет такие манипуляции). Затем, добавив простое утверждение, проверяющее, что емкость вектора (std :: vector ::acity ()) никогда не менялась в начале и в конце всех функций вашего класса, поможет вам убедиться, что память не перемещается.

Например (при условии, что DATA_MAX_SIZE - это максимальный размер по умолчанию, определенный где-то):

template< typename MyType >
class MyData
{
public:
    MyData( unsigned long max_size = DATA_MAX_SIZE )
        : m_max_size( max_size )
        { m_data.reserve( m_max_size ); }

    void add( const MyType& value ) { check_capacity(); m_data.push_back( value ); check_capacity(); }



private:

    std::vector< MyType > m_data;
    const unsigned long m_max_size;

    void check_capacity() { if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); }

};

Или что-то в этом роде ...

2 голосов
/ 02 марта 2009

Создайте свой собственный класс, который будет делегироваться вектору. И проверьте размер в вашем собственном push_back.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...