Program wysypuje się przy usuwaniu tablicy pomocniczej

0

Hej,
piszę program liczący złożoność obliczeniową operacji na tablicach. Wszystko fajnie, ale do momentu, kiedy program będzie tylko robił dwie operacje na raz, a chciałbym, żeby liczył mi wszystko.

Już tłumaczę.
mam kilka funkcji, które liczą czas dodawania na początek, na koniec i gdzieś w środek tablicy.
Poza tym, wcześniej program wczytuje tablicę z pliku.

Tyle słowem wstępu, bo wklejanie całości kodu nie ma sensu

//gdzieś w środku programu
srand( time( NULL ) );
for (int i=0;i<10000;i++){
	
	double t = T.stworz_plik(nazwa_pliku);
	stworz<<t<<endl; //stworz to nazwa pliku
	stworz.flush();
							
	double t1 = T.dodaj(0,losuj(b,c));
	dodajP<<t1<<endl;  //dodajP to nazwa pliku
	dodajP.flush();
				
	double t2 = T.dodaj(d,losuj(b,c));
	dodajK<<t2<<endl;  //dodajK to nazwa pliku
	dodajK.flush();
					
	int indeks = (rand()%T.getwielkosc());                 //Tutaj program losuje mi kilka razy tą samą wartość, później znowu kilka razy inną, dlaczego?
	double t3 = T.dodaj(indeks, losuj(b,c));
	dodajL<<t3<<endl;  //dodajL to nazwa pliku
	dodajL.flush();

}
//gdzieśtam dalej jest zamknięcie plików

Jeśli zakomentuję dwie z trzech akcji dodawania do tablicy (bez znaczenia jakie), to wszystko będzie śmigać.
Program się kompiluje, ale dotarłem do miejsca wysypywania się, jest to zwalnianie tablicy pomocniczej.

Nie mam zielonego pojęcia, dlaczego operacja delete nie działa, jak należy.

//w klasie tablicy
double tablica::dodaj(int indeks, int unsigned wartosc){
	if (indeks<=wielkosc){
		Czas.start();
		wielkosc++;
		int unsigned *tabpom = new int unsigned[wielkosc];
		for (int i=0;i<indeks;i++)
			tabpom[i]=tab[i];
		for (int i=indeks;i<wielkosc;i++)
			tabpom[i+1]=tab[i];
		tabpom[indeks]=wartosc;
		delete[] tab;
		stworz(wielkosc);
		for (int i=0;i<wielkosc;i++)
			tab[i]=tabpom[i];
		delete[] tabpom;                                    //Tutaj program się wywala
		Czas.stop();
	}
	else
		cout<<"BLAD - indeks poza zakresem"<<endl;
	return Czas.wynik();
}

Bardzo Was proszę o pomoc, bo utknąłem w martwym punkcje - zarówno w przypadku zwalniania pamięci, jak i złego losowania.

Pozdrawiam serdecznie
mrozo

5

do generowania liczb pseudolosowych nie uzywa sie juz rand tylko tego
http://en.cppreference.com/w/cpp/numeric/random
np ten bedzie tutaj wystarczajacy
http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

uzywanie golego new i delete jest antyidomem. Powinienes uzywac do tego shared_ptr / unieque_ptr

uzywales debuggera?

        for (int i=indeks;i<wielkosc;i++)
            tabpom[i+1]=tab[i]; 

tu masz wyjscie po za zakres. zastanow sie kiedy. Po wyjsciu po za zakres masz UB wiec zdarzyc moze sie wszystko

do tego czemu tablice? czemu nie vector? Czemu tak bardzo chcesz sprawdzac performance jezeli chodzi o tablice?

5
delete[] tab;
...
for (int i=0;i<wielkosc;i++)
    tab[i]=tabpom[i];

Najpierw usuwasz, a potem używasz.

int unsigned *tabpom = new int unsigned[wielkosc];
....
for (int i=indeks;i<wielkosc;i++)
    tabpom[i+1]=tab[i];

Piszesz do elementu tabpom[wielkosc], czyli poza tablicą.

0
twonek napisał(a):
delete[] tab;
...
for (int i=0;i<wielkosc;i++)
    tab[i]=tabpom[i];

Najpierw usuwasz, a potem używasz.

int unsigned *tabpom = new int unsigned[wielkosc];
....
for (int i=indeks;i<wielkosc;i++)
    tabpom[i+1]=tab[i];

Piszesz do elementu tabpom[wielkosc], czyli poza tablicą.

funkcja "stworz" tworzy tą tablicę na nowo

fasadin napisał(a):

do generowania liczb pseudolosowych nie uzywa sie juz rand tylko tego
http://en.cppreference.com/w/cpp/numeric/random
np ten bedzie tutaj wystarczajacy
http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution

uzywanie golego new i delete jest antyidomem. Powinienes uzywac do tego shared_ptr / unieque_ptr

uzywales debuggera?

        for (int i=indeks;i<wielkosc;i++)
            tabpom[i+1]=tab[i]; 

tu masz wyjscie po za zakres. zastanow sie kiedy. Po wyjsciu po za zakres masz UB wiec zdarzyc moze sie wszystko

do tego czemu tablice? czemu nie vector? Czemu tak bardzo chcesz sprawdzac performance jezeli chodzi o tablice?

Tablica, ponieważ to jest projekt na zajęcia :)

Masakra :O Tyle razy ręcznie testowałem program i dodawałem zmienne wszędzie i nie zauważyłem tego odniesienia poza zakres...

A powiedz mi proszę, dlaczego rand jest złe? Wczoraj generowałem masę dużych plików do testów i nie miałem tego problemu

wszystko odbywało się tą linijką

 uint64_t wylosowana_liczba = ( (rand() * rand() * rand() )%(c-b+1)) + b;
2

funkcja stworz tworzy tablice, ale czy w tym samym miejscu gdzie wskazuje wskaznik tab?

a co to ma za roznice ze na zajecia... jezeli nie jest w wymaganiach to uzyc std::vector

bo sie nie robi tego recznie a za pomoca debuggera

rand jest przestarzale, jezeli piszesz w c++ to powinienes uzywac tego co Ci zalinkowalem

0

No właśnie ma być tablica :)

To w takim razie biorę się za ogarnianie tego linka

A co do tworzenia, to kod poniżej

 
class tablica{
	private:
		int wielkosc;
		int *tab;
		czas Czas;

//************************

void tablica::stworz(int N){
	//metoda tworzy tablice o przeslanym rozmiarze
	wielkosc = N;
	tab = new int unsigned[wielkosc];
	return;

ADD:
Po zaimplementowaniu biblioteki <random> wywala mi Dev'a, program po prostu się crashuje :-(

Co może być powodem?

3

Problemem jest używanie antycznych IDE i kompilatorów ;)

Jak nie możesz zmienić to zostań przy rand. To gorsza praktyka, ale jeśli rozumiesz i akceptujesz jego niedoskonałości to może być akceptowalne, szczególnie w aplikacji gdzie losowość może być bardzo mało losowa i nic się nie stanie. Polecam bardzo wykład podlinkowany przez @spartanPAGE.

0

Fakt, mój kompilator nie był aktualizowany od czasów technikum. Zaktualizowałem go, ale i tak gdzieś mi się coś kopało przy random.
W tym projekcie zostawie już rand, ale podlinkowany wykład na pewno przesłucham.

No cóż, dziękuje Wam bardzo za pomoc, temat do zamknięcia ;-)

1 użytkowników online, w tym zalogowanych: 0, gości: 1