Voit ladata ja asentaa Heob-sovelluksen sivulta https://github.com/ssbssa/heob. Kun olet purkanut tuon johonkin kansioon, lisää tuon kansion polku Qt Creatorissa "Analyze->Heob". Voit ladata ja kopioida samaan kansioon dll tiedostot sivulta https://github.com/ssbssa/dwarfstack
Heob (Heap Observer) on Qt Creatoriin integroitu työkalu, joka auttaa havaitsemaan muistivuotoja Windows-ympäristössä. Tässä harjoituksessa opetellaan tunnistamaan ja korjaamaan muistivuotoja C++-ohjelmissa.
Miksi Heob eikä Valgrind?
Qt Creatorin Analyze-valikossa näkyy myös Valgrind-työkalu, joka on alan standardi muistivuotojen havaitsemiseen. Valgrind ei kuitenkaan toimi Windowsissa - se on käytettävissä vain Linux-järjestelmissä. Heob on kehitetty juuri Windowsia varten ja tarjoaa vastaavan toiminnallisuuden kuin Valgrind Linuxissa.
Muistivuoto tapahtuu, kun ohjelma varaa muistia dynaamisesti (esim. new-komennolla),
mutta ei vapauta sitä (delete-komento puuttuu). Tämä johtaa siihen, että ohjelma kuluttaa
yhä enemmän muistia, mikä voi lopulta kaataa koko järjestelmän.
Yleisiä muistivuotojen syitä:
new) ilman vastaavaa delete-komentoadelete-komennon suorittamisenshared_ptr)Vaihe 1: Käynnistä Heob
Vaihe 2: Aja ohjelma Heobin valvonnassa
Vaihe 3: Analysoi raportti
Heob näyttää tarkat tiedot muistivuodoista:
new)Sivulla https://doc.qt.io/qtcreator/creator-heob.html kerrotaan Heobin asetuksista. Extra arguments-kohtaan kannatta laittaa seuraavaa
-oleaks.html -g2 -L1024Edellisen ansiosta tulokset saadaan html-muodossa.
Tämä on hyvä esimerkki muistivuodoista, koska ongelma on helppo havaita ja korjata. Luo Qt Creator -projekti ja jaa koodi seuraaviin tiedostoihin:
dog.h
#ifndef DOG_H
#define DOG_H
#include <string>
using namespace std;
class Dog {
private:
string name;
public:
Dog(string n);
~Dog();
void bark();
};
#endif // DOG_H
dog.cpp
#include "dog.h"
#include <iostream>
using namespace std;
Dog::Dog(string n) : name(n) {
cout << "Koira " << name << " luotiin" << endl;
}
Dog::~Dog() {
cout << "Koira " << name << " tuhotaan" << endl;
}
void Dog::bark() {
cout << name << " haukkuu!" << endl;
}
main.cpp (SISÄLTÄÄ MUISTIVUODON)
#include "dog.h"
int main() {
for (int i = 0; i < 5; i++) {
Dog* dog = new Dog("Koira" + to_string(i));
dog->bark();
// VIRHE: delete puuttuu!
// Jokaisella kierroksella vuotaa muistia
}
return 0;
}
Ongelma: Silmukka luo 5 Dog-oliota, mutta yhtäkään ei tuhota.
Konsoliin tulostuu vain "luotiin"-viestit, mutta ei yhtään "tuhotaan"-viestiä!
Minulla Heob tuotti seuraan tuloksen tulos1
Korjaus (tapa 1): Lisää delete
Korjaus (tapa 2): Käytä unique_ptr (SUOSITELTU)
#include "dog.h"
#include <memory>
int main() {
for (int i = 0; i < 5; i++) {
auto dog = std::make_unique<Dog>("Koira" + to_string(i));
dog->bark();
// Muisti vapautuu automaattisesti jokaisen kierroksen lopussa
}
return 0;
}
Korjauksen jälkeen Heob tuotti seuraan tuloksen tulos2
Heobin tulos:
leaks.xml-tiedoston projektin ja myös html-tiedoston, jos käytät em. asetuksia build-kansioon<error>-tageja<error>-tageja lainkaanHuom! Heob saattaa raportoida pieniä (esim. 16 tavun) vuotoja, jotka tulevat MinGW:n C++ standardikirjastosta. Nämä ovat vääriä hälytyksiä (false positives) ja voidaan ignoorata. Keskity isoihin vuotoihin ja varsinkin siihen, että "tuhotaan"-viestit tulostuvat konsoliin!
| Huono käytäntö ❌ | Hyvä käytäntö ✅ |
|---|---|
Animal* a = new Dog(); |
auto a = make_unique<Dog>(); |
Animal* arr[] = {new Dog(), new Cat()}; |
vector<unique_ptr<Animal>> arr; |
Manuaalinen delete |
Automaattinen muistinhallinta |
| Riski muistivuodoille | Ei muistivuotoja |
Muista: Modernissa C++:ssa (C++11 ja uudemmat) raakaosoittimien käyttö on harvoin tarpeen.
Käytä aina älykkäitä osoittimia (unique_ptr, shared_ptr), kun tarvitset dynaamista muistinhallintaa!