Domanda

Ho un vettore che sto caricando con una quantità nota di elementi (N).

L'elaborazione crea dinamicamente nuovi elementi, che vengono aggiunti al vettore.

Mi aspetto che vengano creati circa 2 * N elementi aggiuntivi, quindi ridimensiono il vettore su 3 * N.

Se gli elementi aggiuntivi lo superano, vorrei che un programma venisse interrotto, piuttosto che un'espansione dinamica del vettore.

Esiste un modo per rilevarlo, che è portatile tra AIX / TRU64 / Linux?

È stato utile?

Soluzione

Rileva cosa? Se il vettore verrà ridimensionato? Se è stato?

L'unico vero modo per raggiungere questo obiettivo è fornire funzionalità di verifica in un allocatore personalizzato o in una funzione che aggiunge elementi al vettore.

es

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);
}

Altri suggerimenti

Perché stai usando un vettore? L'intero punto del vettore è di espandersi dinamicamente quando necessario.

Invece di creare una classe da delegare al vettore, crea una classe da delegare a un semplice array. Chiedi al tuo push_back di controllare le dimensioni e interrompere quando necessario.

Crea la tua classe che delegherà al vettore. E controlla le dimensioni nel tuo push_back.

Se conosci la dimensione in fase di compilazione, magari usando uno std :: tr1 :: array (o boost :: array ) sarebbe una scelta migliore. Mantiene una dimensione fissa e controlla l'accesso come std :: vector.

Se comunque lo conosci solo in fase di runtime, come già detto qui, dovresti incapsulare il tuo vettore in una classe con funzioni specifiche che controlleranno le condizioni che desideri (tramite affermazioni per esempio).

In quest'ultimo approccio, suggerirei, se puoi conoscere la dimensione massima durante la creazione del vettore, di riservare (std :: vector :: reserve ()) la dimensione massima del vettore nel tuo costruttore di classi incapsulante (o funzione di inizializzazione). In questo modo, non ci saranno più manipolazioni della memoria da parte del vettore stesso (solo se il costruttore / distruttore di elementi vettoriali esegue tali manipolazioni). Quindi, aggiungendo una semplice asserzione che verifica che la capacità vettoriale (std :: vector :: capacity ()) non sia mai cambiata all'inizio e alla fine di tutte le funzioni della tua classe ti aiuterà ad assicurarti che la sua memoria non si sposti.

Ad esempio (supponendo che DATA_MAX_SIZE sia una dimensione massima predefinita definita da qualche parte):

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!" ); }

};

O qualcosa del genere ...

Le classi

??std usano un allocatore chiamato ogni volta che si inserisce un elemento. È possibile scrivere un nuovo allocatore ereditando da std :: alocator e aggiungere tutti i tipi di controlli / tracce necessari.

(L'ho fatto prima ma mi ci è voluto un po 'di tempo per rendere il codice funzionante.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top