Itt történik memória elszivárgás?
//main.cpp
# include <iostream>
# include <stdlib.h>
typedef unsigned short ushort;
typedef unsigned int uint;
using std::cout;
using std::cin;
using std::endl;
class Counter
{
public:
Counter(); //Konstruktor
Counter(int x); //Konstruktor2
Counter(const Counter &); //Másoló konstruktor
~Counter(); //Destruktor
void increment(); //increment
const Counter& operator++ (); //prefix
const Counter operator++ (int); //postfix
void SetVal(int x); //SetVal
int GetVal()const; //GetVal
Counter Add(const Counter &rhs)const;
private:
ushort *itsVal; //*itsVal
};
//konst,konst2,copy konst,destr,
Counter::Counter():
itsVal(new ushort(2))
{cout <<"Konstruktor \n";}
Counter::Counter(int x):
itsVal(new ushort(x))
{cout <<"Konstruktor2 \n";}
Counter::Counter(const Counter &rhs)
{
cout <<"Copy konstruktor \n";
itsVal = new ushort;
*itsVal = rhs.GetVal();
}
Counter::~Counter()
{
cout <<"Destruktor \n";
delete itsVal;
itsVal = NULL;
}
//operator++
const Counter& Counter::operator++ ()
{
++*itsVal;
return *this;
}
const Counter Counter::operator++ (int)
{
++*itsVal;
return *this;
}
//Metódus
void Counter::SetVal(int x)
{*itsVal = x;}
int Counter::GetVal()const
{return *itsVal;}
void Counter::increment()
{++*itsVal;}
Counter Counter::Add(const Counter &rhs)const
{return Counter(*itsVal+rhs.GetVal());}
//main kezdõdik
int main()
{
Counter i(1);
cout <<"i erteke: "<< i.GetVal() << endl;
++i;
cout <<"i erteke: "<< i.GetVal() << endl;
i++;
cout <<"i erteke: "<< i.GetVal() << endl;
return EXIT_SUCCESS;
}
Ez miért nem működik jól:
//main.cpp
# include <iostream>
# include <stdlib.h>
typedef unsigned short ushort;
typedef unsigned int uint;
using std::cout;
using std::cin;
using std::endl;
class Counter
{
public:
Counter(); //Konstruktor
Counter(int x); //Konstruktor2
Counter(const Counter &); //Másoló konstruktor
~Counter(); //Destruktor
void increment(); //increment
const Counter& operator++ (); //prefix
const Counter operator++ (int); //postfix
void SetVal(int x); //SetVal
int GetVal()const; //GetVal
Counter Add(const Counter &rhs)const; //Add *itsVal+rhs.GetVal()
private:
ushort *itsVal; //*itsVal
};
//konst,konst2,copy konst,destr,
Counter::Counter():
itsVal(new ushort(1))
{cout <<"Konstruktor \n";}
Counter::Counter(int x):
itsVal(new ushort(x))
{cout <<"Konstruktor2 \n";}
Counter::Counter(const Counter &rhs)
{
cout <<"Copy konstruktor \n";
itsVal = new ushort;
*itsVal = rhs.GetVal();
}
Counter::~Counter()
{
cout <<"Destruktor \n";
delete itsVal;
itsVal = NULL;
}
//operator++
const Counter& Counter::operator++ ()
{
++*itsVal;
return *this;
}
const Counter Counter::operator++ (int)
{
++*itsVal;
return *this;
}
//Metódus
void Counter::SetVal(int x)
{*itsVal = x;}
int Counter::GetVal()const
{return *itsVal;}
void Counter::increment()
{++*itsVal;}
Counter Counter::Add(const Counter &rhs)const
{return Counter(*itsVal+rhs.GetVal());}
//main kezdõdik
int main()
{
Counter varOne(2),varTwo(3),varThree;
cout <<"varOne: "<< varOne.GetVal() << endl;
cout <<"varTwo: "<< varTwo.GetVal() << endl;
cout <<"varThree: "<< varThree.GetVal() << endl;
varThree = varOne.Add(varTwo);
cout <<"varOne: "<< varOne.GetVal() << endl;
cout <<"varTwo: "<< varTwo.GetVal() << endl;
cout <<"varThree: "<< varThree.GetVal() << endl;
return EXIT_SUCCESS;
}
Az összeadás után a varThree értéke miért lesz 4824 ?
Nem írtál operator=-t, emiatt pointer szintű másolás történik.
Azaz varThree = varOne.Add(varTwo); ebben a sorban egyrészt a varThree által foglalt short elvész, másrészt egy temporális objektum pointerét kapja meg, ami azóta törlődött, tehát akárhova mutathat.
Jah, amúgy a biztonság kedvéért ne csinálj semmit. Legyél tisztában vele, hogy mi történik, és akkor nem lesz ilyen bizonytalanság. A destruktorban 0-t adni a pointernek (amúgy használd a nullptr konstanst 0 vagy NULL helyett) felesleges, hiszen az a mutató utána megsemmisül.
Sőt, úgy általában nincs értelme, csak ha azt akarod jelezni, hogy ez a mutató nem mutat sehova (ÉS később még használod azt a mutatót).
Arról beszélek, hogy amikor ezt a sort hajta végre:
varThree = varOne.Add(varTwo);
Akkor a varThree egy létező objektum, azaz lefutott a konstruktora. Ott hívott egy new-t. A default operator= (értékadó operátor) azt csinálja, hogy átmásolja az összes tagváltozót, a pointereket is. Azaz az Add függvényben létrejövő névtelen Counter objektum (aminek szintén vagy egy new-zott mutatója) pointere felülírja a varThree pointerét, azaz a varThree pointere ugyanoda fog mutatni, mint a névtelen objektumé. Tehát az eredetileg mutatott short elveszett, hiszen már nem mutat rá semmi.
Ezután a névtelen objektum megsemmisül, delete-t hívva az általa mutatott shortra, de a varThree még mindig oda mutat, ezzel undefined behaviort okozva, amikor megpróbálod elérni azt.
Kapcsolódó kérdések:
Minden jog fenntartva © 2025, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!