Kirjoittaja Aihe: [ ratkaistu ] c++ stl-hakemisto ja roskien keruu  (Luettu 3162 kertaa)

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
On kohtalainen joukko merkkijonoalkioita, joita laitetaan c++ sdt:map:iin niin, että yksi alkio on avain ja sen häntänä on vaihtelevan pituinen vektori muita joukon merkkijonoalkioita.

Mikä tahansa joukon merkkijono voi olla avaimena ja mitkä tahansa muut merkkijonoalkiot voivat kuulua sen häntään.

Kun mikä tahansa avaimena oleva merkkijonoalkio tekee muutoksia häntäänsä, hakemistossa korvataan sille uusi, muutettu häntä eli koko avain-häntä-pari korvataan uudella avain-häntä-parilla hakemistossa.

Vanhasta hännästä taitaa tulla roskaa. Osaako std:map huolehtia roskistaan vai jääkö se ohjelmoijan tehtäväksi. Mitä tapahtuu, jos map-rakenteessa muutetaan ja korvaillaan häntiä pitkä aika, kerääntyvätkö roskat jonnekin?


« Viimeksi muokattu: 22.04.24 - klo:11.15 kirjoittanut teele »

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11485
    • Profiili
    • Tomin kotisivut
Vs: c++ stl-hakemisto ja roskien keruu
« Vastaus #1 : 09.04.24 - klo:22.47 »
Et mainininnut, mitä tietorakennetta käytät hännän tallettamiseen, mutta jos käytät esimerkiksi std::string-tyyppiä avaimille ja std::vector<std::string> arvoille, niin kaikki noista kuuluvat sille kuvaukselle (std::map<std::string, std::vector<std::string>>) ja vapautetaan, kun korvaat tai poistat avaimen. Jos käyttäisit osoittimia (new-avainsana), niin joutuisit huolehtimaan vapauttamisesta itse. C++:ssa ei ole roskienkeruuta ellet sellaista itse ohjelmaasi lisää.
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Vs: c++ stl-hakemisto ja roskien keruu
« Vastaus #2 : 13.04.24 - klo:18.00 »
Hakemisto on tosiaan muotoa

std::map<std::string, std::vector<std::string>>

niin kuin vastauksessa.

Kun tästä hakemistosta poistellaan avaimia eripituisine häntineen, niin muistitilaan syntryy erikokoisia koloja, koska poistojärjestys voi olla mikä vain. c++ vapauttaa poistetun tilan, mutta mitä oikeasti tapahtuu muistiavaruuden alueessa, joka sisältää eripituisia vapaita pätkiä siellä täällä. Miten c++ osaa ne hyödyntää tai pirstoukuuko muisti vain ja tarvittava uusi muistitila oteaan uudelta, käyttämättömältä alueelta.


« Viimeksi muokattu: 22.04.24 - klo:10.51 kirjoittanut teele »

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Vs: c++ stl-hakemisto ja roskien keruu
« Vastaus #3 : 22.04.24 - klo:11.14 »

Kysymyksenä oli, vapauttaako c++ oikeasti muistia, kun hakemistoon lisäillään ja sieltä poistellaan avaimia täysin eripituisine häntineen.

Nettiselvittelyn perusteella näyttäisi siltä,

https://lemire.me/blog/2020/03/03/calling-free-or-delete/

https://notes.secretsauce.net/notes/2016/04/08_glibc-malloc-inefficiency.html

https://www.geeksforgeeks.org/delete-and-free-in-cpp/

että vastaus voisi olla muotoa "Saattaapi vapauttaa mutta saattaapi olla vapauttamattakin" eli asia riippuu vapautettavista kooista ja kääntäjän parametreista.

malloc_trim -komennolla voinee vaikuttaa vapauttamistoimintoon, mutta silläkin on omat parametrinsa.

Mielenkiintoinen kokeilu olisi, millaisilla häntäpituuksilla ja malloc_trim -parametrien arvoilla päästäisiin surimpaan tai pieneimpään muistirohmuamiseen.

Mutta ehkä kysymys on ratkennut niin paljon, kuin se harrastelijan kannalta voi ratketa, joten uskaltanen laittaa sen ratkaistuksi?


kamara

  • Käyttäjä
  • Viestejä: 3032
    • Profiili
Vs: [ ratkaistu ] c++ stl-hakemisto ja roskien keruu
« Vastaus #4 : 22.04.24 - klo:13.19 »
Tämä nyt saattaa olla tyhmää, mutta voit katsoa vapautatko kaikki käyttämäsi muistin ohjelman ajon lopetettuasi valgring-ohjelmalla.

https://valgrind.org/

teele

  • Käyttäjä
  • Viestejä: 852
    • Profiili
Vs: [ ratkaistu ] c++ stl-hakemisto ja roskien keruu
« Vastaus #5 : 23.04.24 - klo:20.28 »
valgrind on itselleni uutta ja luultavasti hyödyllistäkin tietoa, pitääpä tutustua aiheeseen.

kiitoksia vihjeestä  :)


Muokk.

pikaisella lukemisella näyttää siltä, että muistintarkistusohjelmat osaavat etsiä vapauttamattomia muistialueita, new  -peräisiä tai mallocoituja tai alueita, joihin on osoite, vaikka osoitetta tai aluetta käytetä enää.

Tällaiset tapaukset ovat vähän kuin ohjelmoijan huolimattomuusvirheitä. Hakemiston tapauksessa std-oliot vapautetaan luultavastikin oman koodin osalta. Mutta jos avaimien hännät ovat eripituisia, vapautettavat muistipätkät ovat erimittaisia ja sijaitsevat siellä täällä koneen muistitilassa.

Pirstaloituva muisti pitäisi kai jotenkin siivota yhtenäiseksi. Toivottavasti kääntäjän tekijät ovat ottaneet asian huomioon?

« Viimeksi muokattu: 23.04.24 - klo:21.35 kirjoittanut teele »

Tomin

  • Palvelimen ylläpitäjä
  • Käyttäjä / moderaattori+
  • Viestejä: 11485
    • Profiili
    • Tomin kotisivut
Vs: [ ratkaistu ] c++ stl-hakemisto ja roskien keruu
« Vastaus #6 : 23.04.24 - klo:22.12 »
Se taitaa kyllä olla enemmän allokaattorin kuin kääntäjän tehtävä varata muistia niin ettei se pirstaloidu. Toisaalta kerran varattua aluetta ei voi vain lähteä siirtelemään, koska siihen voi olla olemassa osoittimia. Käytännössä ohjelmoijan pitäisi itse siirtää olion paikka muistissa.
Automaattinen allekirjoitus:
Lisäisitkö [RATKAISTU] ketjun ensimmäisen viestin aiheeseen ongelman ratkettua, kiitos.