OS: lubuntu 12.10
Kompilator: GNU GCC Compiler (język C++)
IDE: Code Blocks 10.05
Mam sobie oto taki konstruktor klasy:
Macierz::Macierz(int w, int k, int z)
{
wiersze=w;
kolumny=k;
zakres=z;
macierz=new int *[wiersze];
for(int i=0;i
{
macierz[i]=new int[kolumny];
}
}
Teraz chcę napisać do niego poprawny destruktor, który będzie zwalniał alokowaną pamięć dla tejże macierzy. Początkowo korzystałem z “pustego”:
Macierz::~Macierz(void)
{
}
i wszystko działało jak należy. Jednak w obawie, że nastąpi wyciek pamięci, główkuję nad własną definicją destruktora (jest to też projekcik na zaliczenie i stąd takie ambitne plany ). I wpadłem na taki oto pomysł:
Macierz::~Macierz(void)
{
for(int i=0;i
{
delete []macierz[i];
}
delete[] macierz;
}
I podczas wykonywania funkcji zaprzyjaźnionej, np dodawania macierzy, zdefiniowanej następująco:
Macierz Dodaj(Macierz m1, Macierz m2)
{
Macierz dodawanie(m1.wiersze,m1.kolumny,0);
for(int i=0;i
{
for(int j=0;j
{
dodawanie.macierz[i][j]=m1.macierz[i][j]+m2.macierz[i][j];
}
}
return dodawanie;
}
Wywołanie w mainie:
Dodaj(matrix1,matrix2).Wypisz();
Wynik otrzymuję poprawny, jednak tracę wartości macierzy matrix1 i matrix2 (pojawiają się jakieś dziwne, nie wiadomo skąd wartości). Natomiast apogeum jest przy wywołaniu funkcji zaprzyjaźnionej, która ma zmieniać wartości danych macierzy (np. ZmieńZnaki o takim kodzie:)
Macierz ZmianaZnaku(Macierz m1)
{
for(int i=0;i
{
for(int j=0;j
{
m1.macierz[i][j]*=-1;
}
}
return m1;
}
Wtedy wywala coś takiego:
***glibc detected***./Macierz: munmap_chunk(): invalid pointer: 0x08a7d040 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb749bee2]
/lib/i386-linux-gnu/libc.so.6(+0x765c5)[0xb749c5c5]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb7637adf]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdaPv+0x1b)[0xb7637b2b]
./Macierz[0x8049787]
./Macierz[0x8049e3d]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb743f4d3]
./Macierz[0x8048ae1]
======= Memory map: ========
08048000-0804c000 r-xp 00000000 08:05 264831 /home/wojcirej/Dropbox/Macierz/bin/Debug/Macierz
0804c000-0804d000 r--p 00003000 08:05 264831 /home/wojcirej/Dropbox/Macierz/bin/Debug/Macierz
0804d000-0804e000 rw-p 00004000 08:05 264831 /home/wojcirej/Dropbox/Macierz/bin/Debug/Macierz
08a7d000-08a9e000 rw-p 00000000 00:00 0 [heap]
b73f8000-b73fa000 rw-p 00000000 00:00 0
b73fa000-b7424000 r-xp 00000000 08:05 1573549 /lib/i386-linux-gnu/libm-2.15.so
b7424000-b7425000 r--p 00029000 08:05 1573549 /lib/i386-linux-gnu/libm-2.15.so
b7425000-b7426000 rw-p 0002a000 08:05 1573549 /lib/i386-linux-gnu/libm-2.15.so
b7426000-b75c9000 r-xp 00000000 08:05 1573508 /lib/i386-linux-gnu/libc-2.15.so
b75c9000-b75ca000 ---p 001a3000 08:05 1573508 /lib/i386-linux-gnu/libc-2.15.so
b75ca000-b75cc000 r--p 001a3000 08:05 1573508 /lib/i386-linux-gnu/libc-2.15.so
b75cc000-b75cd000 rw-p 001a5000 08:05 1573508 /lib/i386-linux-gnu/libc-2.15.so
b75cd000-b75d1000 rw-p 00000000 00:00 0
b75d1000-b75ed000 r-xp 00000000 08:05 1573533 /lib/i386-linux-gnu/libgcc_s.so.1
b75ed000-b75ee000 r--p 0001b000 08:05 1573533 /lib/i386-linux-gnu/libgcc_s.so.1
b75ee000-b75ef000 rw-p 0001c000 08:05 1573533 /lib/i386-linux-gnu/libgcc_s.so.1
b75ef000-b76cb000 r-xp 00000000 08:05 1182796 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76cb000-b76cc000 ---p 000dc000 08:05 1182796 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76cc000-b76d0000 r--p 000dc000 08:05 1182796 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76d0000-b76d1000 rw-p 000e0000 08:05 1182796 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.17
b76d1000-b76d8000 rw-p 00000000 00:00 0
b76ec000-b76f1000 rw-p 00000000 00:00 0
b76f1000-b76f2000 r-xp 00000000 00:00 0 [vdso]
b76f2000-b7712000 r-xp 00000000 08:05 1573486 /lib/i386-linux-gnu/ld-2.15.so
b7712000-b7713000 r--p 0001f000 08:05 1573486 /lib/i386-linux-gnu/ld-2.15.so
b7713000-b7714000 rw-p 00020000 08:05 1573486 /lib/i386-linux-gnu/ld-2.15.so
bfc93000-bfcb4000 rw-p 00000000 00:00 0 [stack]
Przerwane (core dumped)
I teraz pytanie: Jak poprawnie zdefiniować destruktor, żeby wyeliminować oba te kłopoty?