Newsgroup: it.comp.lang.c++
Titolo: Eccezione???

    Provando ad eseguire il codice del main sotto riportato viene sollevata un'eccezione nel momento in cui viene
eseguito il delete su ins2 senza apparente motivo. Per il resto funziona tutto. Il codice è compilato con BCC 5.5.1
sotto WinMe.
Qualcuno può provarlo e farmi sapere? Grazie a tutti
//------------------------------------------------
// Insieme.h
//
// Insieme (nel senso matematico) di numeri interi
// con operazioni di intersezione, unione, sottrazione,
//------------------------------------------------
#ifndef INSIEME_H
#define INSIEME_H
#include <cstddef>
#include <algorithm>
#include <iostream>
//-------------------------------------------------------------------
//  Class name.....: Insieme
//
//  Description....: Insieme (nel senso matematico) di interi
//
//  Notes..........:
//-------------------------------------------------------------------
class Insieme
{
 public:
  Insieme( int num_of_element, int* element );
  Insieme( const Insieme& b );
  ~Insieme();
  Insieme operator&( const Insieme& b ) const;
  Insieme operator|( const Insieme& b ) const;
  Insieme operator-( const Insieme& b ) const;
  bool in( int num ) const;
 private:
  int* first_elem;
  int num_of_elem;
  friend std::ostream& operator<<( std::ostream&, const Insieme& );
};
//-------------------------------------------------------------------
//                       INLINE Section
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//  Name.............: operator<<
//
//  Description......: stampa su stream
//
//  Notes............:
//-------------------------------------------------------------------
inline std::ostream& operator<<( std::ostream& ostr, const Insieme& ins )
{
 // stampa l'insieme nella forma { a b c d ... }
 int* iter = ins.first_elem;
 ostr << "{";
 for( int i = 0; i < ins.num_of_elem; ++i )
 {
  ostr << " " << iter[i];
 }
 ostr << " }";
 return ostr;
}
#endif // INSIEME_H
#include "Insieme.h"
//-------------------------------------------------------------------
//  Name.............: Insieme :: Insieme
//
//  Description......: Costruttore
//
//  Notes............:
//-------------------------------------------------------------------
Insieme :: Insieme( int num_of_element, int* elements ) : num_of_elem(num_of_element)
{
 // ordina gli elementi in elements
 // non mi andava di riscrivere quicksort
 // ho utilizzato direttamente quello della libreria standard
 std::sort( elements, elements + num_of_elem );
 // eliminiamo i duplicati e creiamo il nuovo vettore della dimensione giusta
 int* p = std::unique( elements, elements + num_of_elem);
 num_of_elem = p - elements;
 first_elem = new int[num_of_elem];
 int* iter = first_elem;
 for( int i = 0; i < num_of_elem; ++i )
  iter[i] = elements[i];
}
//-------------------------------------------------------------------
//  Name.............: Insieme :: ~Insieme
//
//  Description......: distruttore
//
//  Notes............:
//-------------------------------------------------------------------
Insieme :: ~Insieme()
{  delete[] first_elem;  }
//-------------------------------------------------------------------
//  Name.............: Insieme :: Insieme
//
//  Description......: costruttore per copia
//
//  Notes............:
//-------------------------------------------------------------------
Insieme :: Insieme( const Insieme& b )
{
 num_of_elem = b.num_of_elem;
 first_elem = new int[num_of_elem];
 int* iter = first_elem;
 int* iterB = b.first_elem;
 for( int i = 0; i < num_of_elem; ++i )
  iter[i] = iterB[i];
}
//-------------------------------------------------------------------
//  Name.............: Insieme :: in
//
//  Description......: Verifica la presenza di un numero
//
//  Notes............: ricerca binaria ( complessità O( logn ) )
//-------------------------------------------------------------------
bool Insieme :: in( int num ) const
{
 int* iter = first_elem;
 // ricerca binaria
 int i = 0;
 int j = num_of_elem - 1;
 int k = 0;
 while( ( *iter != num ) && ( i <= j ) )
 {
  k = ( i + j ) / 2;
  if( num > iter[k] )
   i = k + 1;
  else
   j = k - 1;
 }
 if( iter[k] == num )
  return true;
 else
  return false;
}
//-------------------------------------------------------------------
//  Name.............: Insieme :: operator&
//
//  Description......: operatore di intersezione
//
//  Notes............: crea un nuovo insieme con gli elementi elem
//                     tali che (
a.in
(elem) && 
b.in
(elem)) == true
//-------------------------------------------------------------------
Insieme Insieme :: operator&( const Insieme& b ) const
{
 // massima dimensione per l'intersezione
 // coincide con la minima fra i due insiemi coinvolti
 int dim = std::min( num_of_elem, b.num_of_elem );
 // insieme intersezione
 int* intersection = new int[dim];
 int* intersection_iterator = intersection;
 // puntatori agli elementi correnti nei due insiemi
 int* iterA = first_elem;
 int* iterB = b.first_elem;
 int count = 0;                    // reale dimensione
 int indexA = 0, indexB = 0;       // contatori per la terminazione del ciclo
 // inserimento dei risultati nell'intersezione
 while( (indexA < num_of_elem) && (indexB < b.num_of_elem) )
 {
  if( *iterA < *iterB )             // elementi di a non in b (no inserimento)
  {
   ++iterA;
   ++indexA;
  }
  else if( *iterB < *iterA )        // elementi di b non in a (no inserimento)
  {
   ++iterB;
   ++indexB;
  }
  else                              // elementi comuni (inserimento)
  {
   *intersection_iterator++ = *iterA++;
   iterB++;
   ++count;
   ++indexA;
   ++indexB;
  }
 }
 //creazione insieme intersezione
 Insieme temp( count, intersection );
 //liberazione memoria temporanea
 delete[] intersection;
 return temp;
}
//-------------------------------------------------------------------
//  Name.............: Insieme :: operator|
//
//  Description......: operatore di unione
//
//  Notes............: crea un nuovo insieme con gli elementi elem
//                     tali che (
a.in
(elem) || 
b.in
(elem)) == true
//-------------------------------------------------------------------
Insieme Insieme :: operator|( const Insieme& b ) const
{
 // max dimensione unione = dim(a) + dim(b)
 int dim = num_of_elem + b.num_of_elem;
 // creazione unione
 int* unione = new int[dim];
 int* unione_iterator = unione;
 //puntatori alle posizioni correnti negli insiemi
 int* iterA = first_elem;
 int* iterB = b.first_elem;
 int count = 0;                  // reale dimensione
 int indexA = 0, indexB = 0;      // contatori per la terminazione del ciclo
 // copia degli elementi che so nell'uno o nell'altro (evitando duplicati)
 while( (indexA < num_of_elem) && (indexB < b.num_of_elem) )
 {
  if( *iterA < *iterB )        // elemento di a non in b (inserimento)
  {
   *unione_iterator++ = *iterA++;
   ++count;
   ++indexA;
  }
  else if( *iterB < *iterA )   // elemento di b non in a (inserimento)
  {
   *unione_iterator++ = *iterB++;
   ++count;
   ++indexB;
  }
  else                         // elemento in a ed in b
  {                            //(inserimento evitiamo di copiarlo 2 volte )
   *unione_iterator++ = *iterA++;
   iterB++;
   ++count;
   ++indexA;
   ++indexB;
  }
 }
 // adesso dobbiamo copiare tutti gli elementi dell'insieme di dimensione maggiore
 // ancora rimasti
 while( indexA < num_of_elem )
 {
  *unione_iterator++ = *iterA++;
  ++count;
  ++indexA;
 }
 while( indexB < b.num_of_elem )
 {
  *unione_iterator++ = *iterB++;
  ++count;
  ++indexB;
 }
 // creiamo il nuovo insieme
 Insieme temp( count, unione );
 //eliminazione memoria temporanea
 delete[] unione;
 return temp;
}
//-------------------------------------------------------------------
//  Name.............: Insieme :: operator-
//
//  Description......: operatore differenza
//
//  Notes............: crea un nuovo insieme con gli elementi elem
//                     tali che ( 
a.in
(elem) && !
b.in
(elem) ) == true
//-------------------------------------------------------------------
Insieme Insieme :: operator-( const Insieme& b ) const
{
 // max dimensione della differenza = dim(a)
 int dim = num_of_elem;
 // creazione differenza
 int* differenza = new int[dim];
 int* diff_iterator = differenza;
 //puntatori alle posizioni correnti nei due insiemi
 int* iterA = first_elem;
 int* iterB = b.first_elem;
 int count = 0;                     //dimensione reale della differenza
 int indexA = 0, indexB = 0;      // contatori per la terminazione del ciclo
 while( (indexA < num_of_elem) && (indexB < b.num_of_elem) )
 {
  if( *iterA < *iterB )             // elemento in a ma non in b (inserimento)
  {
   *diff_iterator++ = *iterA++;
   ++count;
   ++indexA;
  }
  else if( *iterB < *iterA )        // elemento in b (no inserimento)
  {
   ++iterB;
   ++indexB;
  }
  else         // elemento comune (no inserimento)
  {
   ++iterA;
   ++iterB;
   ++indexA;
   ++indexB;
  }
 }
 //eventuali elementi di a rimasti
 while( indexA < num_of_elem )
 {
  *diff_iterator++ = *iterA++;
  ++count;
  ++indexA;
 }
 // Insieme differenza
 Insieme temp( count, differenza );
 //eliminazione memoria temporanea
 delete[] differenza;
 return temp;
}
//---------------------------------------
// Main.cpp
//---------------------------------------
#include <cstdlib>
#include <iostream>
#include "Insieme.h"
int main()
{
 int ins1[] = { 1, 5, 17, 4, 12, 29, 21, 37, 1, 5, 29 };
 int ins2[] = { 1, 5, 109, 27, 38, 54, 13, 12, 29 };
 Insieme insieme1( 11, ins1 );
 Insieme insieme2( 9, ins2 );
 std::cout << "Insieme1 = " << insieme1 << std::endl;
 std::cout << "Insieme2 = " << insieme2 << std::endl << std::endl;
 Insieme intersection = insieme1 & insieme2;
 Insieme unione = insieme1 | insieme2;
 Insieme diff1 = insieme1 - insieme2;
 Insieme diff2 = insieme2 - insieme1;
 std::cout << "Intersezione = " << intersection << std::endl;
 std::cout << "Unione = " << unione << std::endl;
 std::cout << "Differenza1 = " << diff1 << std::endl;
 std::cout << "Differenza2 = " << diff2 << std::endl;
 std::cout << "5 e' presente in insieme1? " << std::boolalpha << 
insieme1.in
(5) << std::endl;
 std::cout << "3 e' presente in insieme1? " << std::boolalpha << 
insieme1.in
(3) << std::endl;
 std::cout << "109 e' presente in insieme2? " << std::boolalpha << 
insieme2.in
(109) << std::endl;
 std::cout << "55 e' presente in insieme2? " << std::boolalpha << 
insieme2.in
(55) << std::endl;
 delete[] ins1;
 delete[] ins2;    // qui viene sollevata un'eccezione sia in modalità debug che release.
                          // In ambiente Windows c'è la possibilità che sia una Structured Exception del SO e non del
C++
 std::system("PAUSE");
 return 0;
}

 Qualcuno puņ provarlo e farmi sapere? Grazie a tutti
A volte mi chiedo se ci sono o ci faccio. Forse le due nottate insonni si stanno facendo sentire, ma ca***te del genere
non ne avevo mai scritte. Dimenticate questa mail!
( E' Vergognoso con la V maiuscola :-|)
Fulvio


Ciao,
non preoccuparti, a volte si fa di peggio in codice di produzione.
Maurus