Struktura ve frontě - memory leak? – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Struktura ve frontě - memory leak? – C / C++ – Fórum – Programujte.comStruktura ve frontě - memory leak? – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené — příspěvek s řešením.
24. 11. 2014   #1
-
0
-

ahoj, 

typedef struct {
  int delka;
  char *p;
} zprava;

std::queue<zprava> fronta;

Předpokládám, že když udělám 

zprava neco;

neco.p = malloc(pozadovana_velikost);
fronta.push(zprava);

vytvoří se plytká kopie struktury (asi pomocí new), která se uloží do fronty. Pokud pak strukturu z fronty vyjmu 

zprava cosi;

cosi = fronta.front();
fronta.pop();
free(cosi.p);

dojde k vytvoření plytké kopie v proměnné cosi a odstranění (delete) struktury z fronty. Jsou předpoklady správné?

Přestože je fronta před ukončením programu prázdná, při jeho ukončení mi CodeGuard tvrdí, že objekt nebyl odstraněn. Podle adresy je to struktura, která byla vložena do fronty. Vůbec nerozumím proč.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:8fa:4c7...–
KIIV
~ Moderátor
+43
God of flame
24. 11. 2014   #2
-
0
-

#1 hlucheucho
nejen to, kopie se udela pri vkladani do fronty i pri vybirani z ni.. a jeste se nejspis pri vybirani zneuzije i assign operator (jelikoz tam davas strukturu a ne radsi jen pointer)

Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
KIIV
~ Moderátor
+43
God of flame
24. 11. 2014   #3
-
0
-

   

#include <iostream>
#include <queue>
#include <cstdlib>

using namespace std;

struct zprava {
  int delka;
  char *p;

  zprava() { cout << " konstruktor: " << this << endl; }
  ~zprava() { cout << " destruktor: " << this << endl; }
  zprava(const zprava & b):delka(b.delka), p(b.p) { cout << " konstruktor: " << this << " z " << &b << endl; }
  zprava & operator=(const zprava & b) { delka=b.delka; p=b.p; cout << " assigment: " << this << " z " << &b << endl; return *this; }
};

std::queue<zprava> fronta;

int main() {
  {
    cout << "zprava neco;\n";
    zprava neco;

    neco.p = (char*)malloc(20);
    cout << "fronta.push(neco);\n";
    fronta.push(neco);
    cout << "ende 1\n";
  }

  {
    cout << "zprava cosi;\n";
    zprava cosi;

    cout << "cosi = fronta.front();\n";
    cosi = fronta.front();

    cout << "fronta.pop();\n";
    fronta.pop();

    free(cosi.p);
    cout << "ende 2\n";
  }
}
==4109== Memcheck, a memory error detector
==4109== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==4109== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==4109== Command: ./a.out
==4109== 
zprava neco;
 konstruktor: 0x7ff000420
fronta.push(neco);
 konstruktor: 0x5a03380 z 0x7ff000420
ende 1
 destruktor: 0x7ff000420
zprava cosi;
 konstruktor: 0x7ff000420
cosi = fronta.front();
 assigment: 0x7ff000420 z 0x5a03380
fronta.pop();
 destruktor: 0x5a03380
ende 2
 destruktor: 0x7ff000420
==4109== 
==4109== HEAP SUMMARY:
==4109==     in use at exit: 0 bytes in 0 blocks
==4109==   total heap usage: 5 allocs, 5 frees, 1,172 bytes allocated
==4109== 
==4109== All heap blocks were freed -- no leaks are possible
==4109== 
==4109== For counts of detected and suppressed errors, rerun with: -v
==4109== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Nahlásit jako SPAM
IP: 94.113.95.–
Program vždy dělá to co naprogramujete, ne to co chcete...
24. 11. 2014   #4
-
0
-

Ještě větší záhada.  

class Klient
{
  std::queue<zprava> fronta;

  Klient();
  ~Klient();
  //dalsi atributy a metody
};

class ClientTCP : public TThread  //TThread je z VCL
{
public:
  Klient MySoket;
};

K mému překvapení není volán destruktor instance třídy Klient při uvolnění potomka TThread, ten se má uvolnit z paměti sám. Možná to spolu souvisí. 

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:8fa:4c7...–
Řešení
24. 11. 2014   #5
-
0
-
Vyřešeno Nejlepší odpověď

Záhada vyřešena. Je potřeba zavolat metodu Terminate() u TThread i při ukončení aplikace, pak se korektně vlákno ukončí a spolu s tím se i zavolají destruktory. Bez tohoto opatření aplikace vlákno nějak ukončí, ale není jistota, že zavolá destruktory členských objektů TThread a následně vzniká memory leak.

Opět se ukázala mizerná kvalita dokumentace Embarcadera.

hu 

Nahlásit jako SPAM
IP: 2001:67c:1222:800:8fa:4c7...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 70 hostů

Podobná vlákna

Memory leak — založil Duin

Memory leak — založil CommanderZ

.NET Memory leak — založil RomanZ

Windows Service memory leak — založil hlucheucho

Memmory leak — založil Jakub

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý