Lov na bagove
Program učitava n ocena i ispisuje medijanu, broj ocena iznad 8, i najbolju ocenu. Sadrži četiri greške u radu sa memorijom.
Prevesti sa -g -fsanitize=address,undefined i pokrenuti na probnom ulazu. ASan se zaustavlja na prvoj grešci: pročitati vrstu greške i liniju, ispraviti, pokrenuti opet. Ponoviti dok izvršavanje ne bude bez dodatnog izveštaja.
g++ -std=c++17 -Wall -Wextra -g -fsanitize=address,undefined main.cpp
Za svaku grešku zapisati njeno ime (curenje memorije, viseći pokazivač, dvostruko oslobađanje, ili pristup van niza) i ispravku u jednoj liniji.
Ulaz
U prvom redu učitava se broj ocena n n ocena (celi brojevi 5..10).
Izlaz
Ispisati medijanu nakon sortiranja. Ispisati broj ocena strogo većih od 8. Ispisati najveću ocenu.
Primer
Ulaz
6
7 9 10 6 9 8
Izlaz
9
3
10
Postavka
main.cpp
// Program sadrzi CETIRI greske u radu sa memorijom.
// Prevesti sa -g -fsanitize=address i pokrenuti na probnom ulazu.
//
// Za svaku gresku zapisati njeno ime sa predavanja (curenje memorije, viseci
// pokazivac, dvostruko oslobadjanje, ili pristup van niza) i ispravku.
#include <algorithm>
#include <iostream>
namespace matf
{
int* ucitaj_ocene(int n)
{
int* g = new int[n];
for (int i = 0; i < n; ++i)
std::cin >> g[i];
return g;
}
int medijana(const int* g, int n)
{
int* sortirano = new int[n];
for (int i = 0; i < n; ++i)
sortirano[i] = g[i];
std::sort(sortirano, sortirano + n);
return sortirano[n / 2];
}
int broj_iznad(const int* g, int n, int granica)
{
int k = 0;
for (int i = 0; i <= n; ++i)
if (g[i] > granica)
++k;
return k;
}
const int* najbolja(const int* g, int n)
{
const int* b = g;
for (int i = 1; i < n; ++i)
if (g[i] > *b)
b = g + i;
return b;
}
} // namespace matf
int main()
{
int n;
std::cin >> n;
int* ocene = matf::ucitaj_ocene(n);
int* rezerva = ocene;
std::cout << matf::medijana(ocene, n) << std::endl;
std::cout << matf::broj_iznad(ocene, n, 8) << std::endl;
const int* b = matf::najbolja(ocene, n);
delete[] ocene;
std::cout << *b << std::endl;
delete[] rezerva;
return 0;
}
Rešenje
main.cpp
#include <algorithm>
#include <iostream>
namespace matf
{
int* ucitaj_ocene(int n)
{
int* g = new int[n];
for (int i = 0; i < n; ++i)
std::cin >> g[i];
return g;
}
// O(n log n)
int medijana(const int* g, int n)
{
int* sortirano = new int[n];
for (int i = 0; i < n; ++i)
sortirano[i] = g[i];
std::sort(sortirano, sortirano + n);
int m = sortirano[n / 2];
delete[] sortirano; // ispravka curenja memorije
return m;
}
// O(n)
int broj_iznad(const int* g, int n, int granica)
{
int k = 0;
for (int i = 0; i < n; ++i) // ispravka pristupa van granica niza
if (g[i] > granica)
++k;
return k;
}
// O(n); pokazivac na najbolju ocenu.
const int* najbolja(const int* g, int n)
{
const int* b = g;
for (int i = 1; i < n; ++i)
if (g[i] > *b)
b = g + i;
return b;
}
} // namespace matf
int main()
{
int n;
std::cin >> n;
int* ocene = matf::ucitaj_ocene(n);
std::cout << matf::medijana(ocene, n) << std::endl;
std::cout << matf::broj_iznad(ocene, n, 8) << std::endl;
const int* b = matf::najbolja(ocene, n);
std::cout << *b << std::endl;
delete[] ocene;
// ispravka dvostruku oslobadjanje memorije;
// ispravka viseci pokazivac
return 0;
}