Avatar
expoox
Redaktor
Avatar
expoox:

Ahoj, potrebujem v programe robit hlboku kopiu u copy constructor a aj som si myslel ze ju robim ale zrejme nie, neviete mi prosim povedat preco to robi plytku ?

class CData
{
    private:
        uint32_t version;
        uint8_t block[BLOCK_SIZE];

    public:
        CData(void) {version = 0;}
        ....
        CData & operator=(const CData & a){
            version = a.version;
            for (int i = 0; i < BLOCK_SIZE; i++)
                block[i] = a.block[i];

            return *this;
        }
};

struct ver
{
        CData * binFileArch;
        uint32_t usedArch;
        uint32_t actualSizeArch;
        uint32_t posArch;
};

class CFile
{
...
    private:
        CData * binFile;
        uint32_t used;
        uint32_t actualSize;
        uint32_t pos;

        ver * backUp;
        uint32_t numOfBackUps;
};

CFile::CFile (void) {
    used = 0;
    binFile = new CData[SIZE];
    actualSize = SIZE;
    pos = 0;
    numOfBackUps = 1;
    backUp = new ver[BACKUP_SIZE];
    for (uint32_t i = 0; i < BACKUP_SIZE; i++)
        backUp[i].binFileArch = new CData[SIZE];

}

CFile::CFile (const CFile & a) {     // kopirujuci konstruktor
    binFile = new CData[SIZE];
    binFile = a.binFile;
    used = a.used;
    actualSize = a.actualSize;
    pos = a.pos;
    numOfBackUps = a.numOfBackUps;
    backUp = new ver[BACKUP_SIZE];
    for (uint32_t i = 0; i < BACKUP_SIZE; i++)
        backUp[i].binFileArch = new CData[SIZE];

    for (uint32_t i = 0; i < a.numOfBackUps; i++){
        backUp[i].actualSizeArch = a.backUp[i].actualSizeArch;
        backUp[i].posArch = a.backUp[i].posArch;
        backUp[i].usedArch = a.backUp[i].usedArch;
        *(backUp[i].binFileArch) = *(a.backUp[i].binFileArch);
    }
}
 
Odpovědět 24. dubna 9:05
Avatar
B42P6
Člen
Avatar
Odpovídá na expoox
B42P6:

Ahoj, nepozrel som sa na to veľmi presne, ale vidím tam jednu chybu:

binFile = new CData[SIZE];
binFile = a.binFile;

Na to, prečo to je chyba a ako ju opraviť musíš prísť sám.

Nahoru Odpovědět 24. dubna 13:45
'long long long' is too long for GCC
Avatar
expoox
Redaktor
Avatar
Odpovídá na B42P6
expoox:

bolo to toto, vsak ?

(*binFile) = (*a.binFile);
 
Nahoru Odpovědět 24. dubna 14:30
Avatar
B42P6
Člen
Avatar
Odpovídá na expoox
B42P6:

Ehm... nie. binfile je ukazateľ. Takže toto:

binFile = new CData[SIZE];

Alokuje novú pamäť a ukazateľ na ňu uloží do binFile.

A toto:

binFile = a.binFile;

uloží do binFile ukazateľ na a.binFile. Čiže si natrvalo stratil pamäť ktorú si alokoval (pretože si prepísal hodnotu v binFile) čím vzniká memory leak a binfile teraz ukazuje na a.binFile, čiže každá operácia s týmto ukazateľom zmení aj hodnoty v druhej triede.
Riešenie: musíš skopírovať celé dynamické pole (tak ako si to urobil s backUp)

BTW: Urob si v projekte poriadok (prípadne si ho lepšie navrhni) je tam veľa ďalších chýb , napr:

Tu alokuješ dynamické pole:

backUp[i].binFileArch = new CData[SIZE];

A tu potom len zmeníš prvý prvok:

*(backUp[i].binFileArch) = *(a.backUp[i].binFileArch);
Nahoru Odpovědět 24. dubna 17:28
'long long long' is too long for GCC
Avatar
expoox
Redaktor
Avatar
Odpovídá na B42P6
expoox:

no ale

binFile = a.binFile;

by malo podla mna zavolat pretazeny operator= triedy CData (to iste aj v druhom pripade co popisujes) a tak riesit presne toto, ci to chapem zle ?

 
Nahoru Odpovědět 24. dubna 18:42
Avatar
B42P6
Člen
Avatar
Odpovídá na expoox
B42P6:

Nie, nezavolá pretažený operátor= na toto si sa pýtal už tu: http://www.itnetwork.cz/…71b5588cc3b9#…
A aj keby si na tom zavolal pretažený operátor:

*binFile = *a.binFile;

Čo by sa tým vyriešilo?
binFile je ukazateľ na dynamické pole, a ty meníš len prvý prvok v tomto poli (presne rovnaký problém som popísal v predošlom príspevku). Skús si precvičiť ukazatele, dynamickú alokáciu, atd... . Pretože v tom máš pravdepodobne nejasno.

Nahoru Odpovědět 24. dubna 19:02
'long long long' is too long for GCC
Avatar
Veles
Člen
Avatar
Veles:

V konštruktoroch sa nevolá automaticky funkcia s operátorom priradenia, ak by si to chcel urobiť, tak tú funkciu tam musíš vypísať. čiže tvoj kód:

binFile = a.binFile;

Urobí to, čo napísal B42P6, ale keď napíšeš napr. do

int main()
{
        Trieda = Trieda2;
}

Tak vtedy sa sa zavolá funkcia s operátorom priradenia.

Ak by si chcel aby sa zavolala funkcia s operátorom priradenia, tak musíš spraviť toto:

binFile->operator=(a.binFile);

Ale tu som si nie istý, či to tak môže byť, pretože len nedávno som začal robiť s triedami.

 
Nahoru Odpovědět 16. května 11:47
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.