Funkcja zwraca głupoty, jeśli w danym miejscu nie będzie instrukcji std::cout :)

0

Witam.

Jestem w trakcie tworzenia projektu na studia z budowy i analizy algorytmów. Uprzedzam więc, że algorytm mam gotowy, więc nie chodzi mi o pomoc przy wykonywaniu projektu. Mam za to dość ciekawy problem z kodem realizującym ten algorytm.

Otóż napisałem funkcję, która w zadanej tablicy jednowymiarowej odnajduje element o najwyższej wartości, a następnie zlicza ilość jego wystąpień. Funkcja prezentuje się następująco:

int maxCounter(int *table, unsigned int tableSize)
{
	int max, counter = 0;

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]>max)
			max = table[n];

	}

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]==max)
			counter++;
	}

	return counter;
}

Wywołuję więc funkcję i zadaję jej jakąś tablicę. W wyniku otrzymuję zero :) Postanowiłem przeanalizować działanie algorytmu i w drugiej pętli wewnątrz instrukcji warunkowej, dodałem

std::cout << table[n] << "\n"; 

coby sprawdzić, czy instrukcja warunkowa w ogóle wykonuje się. Po skompilowaniu programu nagle okazało się, że wszystko działa. Tak więc moje pytanie - co jest przyczyną takiego egzotycznego działania programu? Czyżby kompilator coś namieszał (g++ 4.9.2), czy może zwyczajnie ja coś spierdzieliłem? :) A jeśli tak, to co?

2
int max,
if(table[n]>max) //here be dragons
if(table[n]==max) //here be dragons

UB przyjacielu, ub.

0

Pokaż kod który działa i który nie działa.

0

Kod, który działa:

#include <iostream>

int maxCounter(int table[], unsigned int tableSize)
{
	int max, counter = 0;

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]>max)
			max = table[n];

	}

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]==max)
		{
			std::cout << table[n] << "\n";
			counter++;
		}
	}

	return counter;
}

int main()
{
	int tablica[] = { 92, 5, 74, 3, 71, 35, 92, 9, 14, 71, 71, 22, 1, 92 };
	std::cout << maxCounter(tablica, sizeof(tablica)/sizeof(int)) << std::endl;

	return 0;
} 

Kod, który nie działa:

 #include <iostream>

int maxCounter(int table[], unsigned int tableSize)
{
	int max, counter = 0;

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]>max)
			max = table[n];

	}

	for(int n=0; n<tableSize; n++)
	{
		if(table[n]==max)
		{
			counter++;
		}
	}

	return counter;
}

int main()
{
	int tablica[] = { 92, 5, 74, 3, 71, 35, 92, 9, 14, 71, 71, 22, 1, 92 };
	std::cout << maxCounter(tablica, sizeof(tablica)/sizeof(int)) << std::endl;

	return 0;
}

Niestety, odpowiedź kolegi spartanPAGE nie jest dla mnie zbyt zrozumiała. Przeanalizowałem sobie na spokojnie wywołanie funkcji i nie wiem, co mogłem skopać w tych miejscach. Chociaż pierwsza instrukcja warunkowa będzie problematyczna, jeśli w tablicy będą wyłącznie liczby ujemne.

2
kij3k napisał(a):

Czyżby kompilator coś namieszał (g++ 4.9.2)
Ogólnie możliwe, ale raczej nie w tym przypadku.

czy może zwyczajnie ja coś spierdzieliłem? :)
Tak.

A jeśli tak, to co?
Nie zainicjalizowałeś max, więc początkowo może mieć bardzo dużą wartość i to ta wartość będzie potem tym maksem. Poza tym, odczytanie niezainicjalizowanej zmiennej to UB.

Poza tym nie wiem po co tak się męczysz z tą funkcją, kiedy można w 3 linijki:

int maxCounter(int *table, unsigned int tableSize)
{
    int max = *max_element(table, table + tableSize);
    int counter = count(table, table + tableSize, max);
    return counter;
}
0

Istotnie :) W momencie pisania funkcji, w mojej głowie musiało pojawić się dziwne przeświadczenie, iż obie zmienne tak zainicjowane otrzymają wartość zero. Dziękuję serdecznie za pomoc, jak i za wytłumaczenie, czym jest UB.
A z funkcją męczę się w ten sposób, gdyż specyfika przedmiotu wymaga niskopoziomowej implementacji. Bo przecież nie skorzystam z dobrodzejstw STL'a, gdy przyjdzie mi napisać sortowanie :)
Jeszcze raz dzięki za pomoc.

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