gubienie wskaźników w obiekcie przy przekazywaniu przez referencję

0

Cześć!
Czy wiadomo komuś coś na temat następującego problemu?:

Przekazuję do funkcji przez referencję trzy obiekty, które zawierają m.in. dynamiczną wielowymiarową tablicę wskaźników do innego rodzaju obiektów, a dokładniej drzew. Funkcja krzyżuje ze sobą dwa obiekty i wynik zapisuje w trzecim (tak, chodzi o programowanie genetyczne).

Okazuje się, że przy kopiowaniu powstają jakieś błędy - pojawiają się gdzieniegdzie inne liczby, niż w oryginałach. Podprocedury mam ostro zdebugowane - używałem ich w kilku programach i wywoływałem je coś rzędu bilionów razy bez błędu. Nie wiem czy to błąd środowiska, kompilatora, czy czegoś podobnego (używam antycznego DevC++ 5.4.0 i kompilatora MinGW GCC 4.7.2 32-bit, ale na 64-bitowym procesorze Intel i3, windows 8.1)

kod wygląda mniej więcej tak: (tylko najistotniejsze fragmenty)

class Wezel
{
	public:
		
		int operacja;
		Wezel* arg1;
		Wezel* arg2;

		Wezel* Wezel::kopiuj()
		{
			Wezel* nowy=new Wezel;
			nowy->operacja = this->operacja;
			
			if (operacja<0)
			{
				nowy->arg1 = this->arg1->kopiuj();
				nowy->arg2 = this->arg2->kopiuj();
			}
			else
			{
				nowy->arg1 = NULL;
				nowy->arg2 = NULL;
			}
			
			return nowy;
		}
};
class Chromosom
{
	public:
		int ilosc_genow;
		int ilosc_blokow;
		
		int** dlugosci_blokow;
		int*** kod;
		Wezel*** las;
};
int krzyzuj_plytko(Chromosom& A, Chromosom& B, Chromosom& C)
{
	C.ilosc_genow=1;
	C.ilosc_blokow=8;
	
	int punkt_podzialu=losuj(7);
	
	for ( int i=0 ; i<punkt_podzialu+1 ; i++ )
	{
		C.las[0][i]=A.las[0][i]->kopiuj();
	}
	
	for ( int i=punkt_podzialu+1 ; i<C.ilosc_blokow ; i++)
	{
		C.las[0][i]=B.las[0][i]->kopiuj();
	}

przed i po wywołaniu funkcji zwalniam ładnie i deklaruję pamięć chromosomu C. dozwolone są wartości "operacji" od -16 do 9 (ujemne kodują funkcje, nieujemne wartości), a po skrzyżowaniu wyskakują mi całkiem ładne drzewa, z tym, że pojawiają się wartości spoza tego zakresu - ale co ciekawe - max 16, jak też w ogóle inne niż w oryginale

dla przykładu wklejam kody przykładowych A i B oraz C, który powinien najpierw zawierać linijki z A aż do punktu podziału, a potem linijki z B.

//plik A.txt
bloki instrukcji:
gen1:
-14	3	6
-7	8	5
0
8
5
5
-9	5	6
8
//plik B.txt
bloki instrukcji:
gen1:
3
8
6
-8	3	0
-15	9	-3	2	8
4
7
9
//plik C.txt
bloki instrukcji:
gen1:
-10	3	6
-7	-5	0	7	5
0
8
5
5
-9	5	12
9
0

Na 99% to jest twój błąd. Nie szukaj problemów z kompilatorem ani środowiskiem. Czemu tego zwyczajnie nie zdebugujesz? Postaw breakpoint w tej funkcji która wpisuje dziwne wartości i ustaw warunek że wartość jest spoza zakresu, co to za problem?
Ja obstawiam że gdzieś robisz off-by-one i wyłazisz poza zaalokowane tablice, co przy potrójnych wskaźnikach wcale nie jest takie trudne do zrobienia ;]

0

to już kilka tygodni nad tym siedzę, nie pisałbym gdyby to był łatwy problem ;) w każdym razie widzę, że po wstawieniu funkcji w miejsce wywołania problem nie znika, ale kopiowanie z jednego drzewa działa dobrze

0

błąd był w innej procedurze - powstawał podczas mutacji kodu, ale ujawniał się dopiero po krzyżowaniu... kopiując ją z innego programu zapomniałem, że ograniczyłem ilość elementów do wyboru - stąd losowane były czasem symbole spoza zakresu.

Lekcja z tego jest taka, że dopisując nową funkcję do dobrze zdebugowanego programu błąd najpewniej jest w tej nowej funkcji albo w złych wartościach zmiennych globalnych, których używają inne funkcje...

1

@Śmigło czasem bywa gorzej, podobny błąd spowodował katastrofę pierwszej rakiety Ariane 5 -> https://en.wikipedia.org/wiki/Cluster_(spacecraft)#Launch_failure też wzięli przetestowaną część softu z Ariane 4 :)

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