statki[a]=statek(0,0,1,true);
1. tworzysz obiekt tymczasowy statek na stosie.
2. następnie konstruktor kopiujący obiektu statek[a] kopiuje całą zawartość obiektu tymczasowego - wartość zmiennej uszkodzenie (adres buforu) i zmienną dlugosc.
2 alternatywny. Konstruktor kopiujący jest wywoływany dwa razy - raz dla przekazania argumentu do konstruktora kopiującego statek[a], a potem w samym statek[a]. W takiej sytuacji delete w destruktorze argumentu konstruktora kopiującego statek[a] w argumencie dostanie adres już zwolnionego buforu. W normalnej sytuacji nic się nie stanie (delete nie powoduje wyjątków), ale wersja do debugowania pod debugerem specjalnie łapie takie rzeczy. Stąd błąd w destruktorze.
Zapewne w wersji skompilowanej w wersji debug zachodzi druga sytuacja, w wersji release pierwsza (kompilator optymalizuje i konstruktor kopiujący jest wywoływany tylko raz).
3. obiekt tymczasowy jest niszczony, a pamięć zaalokowana jest dealokowana*.
4. w którymś miejscu, odwołujesz się do zmiennej uszkodzenie w statek[x]. Jest to adres zdealokowanego bufora - nic tam nie ma. Występuje błąd.
Rozwiązania (od najlepszego do najgorszego):
1. Zamień bool *uszkodzenie na vector<bool> uszkodzenie.
2. nadpisz konstruktor kopiujący tak, żeby kopiował zawartość buforu, a nie tylko adres.
3. użyj boost::shared_array, zlicza on referencje, zwolni obiekt kiedy w całym programie nie będzie do niego referencji.
4. zabroń kopiowania (prywatny konstruktor kopiujący) i stwórz metodę initialize (konstruktor w miejscu).
* powinieneś użyć delete [], a nie delete. Ale dla typów prostych efekt jest taki sam.
P.S. Do wypełniania pamięci użyj std::fill zamiast pętli.
fill(uszkodzenie, &uszkodzenie[dlugosc], 0);
Czytelniej i krócej.