Zwalnianie pamięci po dwu-wymiarowej tablicy

0

Szybkie pytanko szybka odpowiedź, dlaczego niepoprawnie zwalniam pamięć po tej 2-wym tablicy? Dodatkowo dostaje błąd:

  • Error in `(...)': double free or corruption (top): 0x087e5120 ***
    char **dane;
    int k = 1000;
    int w = 1000;

    dane = new char *[w];
    for(int i=0; i<w; i++)
    {
        dane[i] = new char[k];
    }

    for ( int i = 0; i < 1000; i++ )
    {
        for ( int j = 0; j < 1000; j++ )
        {
            thousand>>dane[i][j];
        }
    }

    for(int i=0; i<w; i++)
      delete [] dane[i];

    delete [] *dane; 
3
  1. używanie nagiego new i delete to antyidiom w C++, używaj smart pointerów i kontenerów. Tutaj np. vector wydaje się idealnym rozwiązaniem.
  2. delete [] *dane; to jest to samo co delete[] dane[0]; Zbędna dereferencja wskaźnika.
1

delete [] *dane;

0

więc wystarczy

delete[] *dane; 

tak?

0

Nie. W jaki sposób to wywnioskowałeś ze zdania "zbędna dereferencja wskaźnika w delete[] *dane"?

1

dane = new char *[w]; delete [] *dane;
Powinieneś zwalniać pamięć tam gdzie ją przydzielasz. A double free wzięło się stąd, że jak @kq wspomniał *dane to to samo co dane[0], a pamięc pod tym adresem już zwolniłeś - o tu

for(int i=0; i<w; i++)
    delete [] dane[i];
0

W takim razie nie bardzo rozumiem o co Ci chodzi. Czy zwalnianie tablic dwuwymiarowych jest takie samo jak zwalnianie tablic jednowymiarowych? Czy wystarczy jak napiszę

delete [] dane; 

?

2

To nie jest tablica dwuwymiarowa, tylko tablica wskaźników (ew. możesz to traktować jako tablicę tablic). To będzie ok, pod warunkiem, że zwolnisz wszystkie przydzielone tablice przypisane do elementów dane (co robisz w oryginalnym poście).

Ale i tak zamiast się tak męczyć i pisać zły kod powinieneś użyć jak człowiek kontenera z biblioteki standardowej.

3

Dokładnie tak ma być. Tak jak napisałem, pamięc zwalniasz tam gdzie ją przydzieliłeś, czyli w Twoim przypadku:

    for(int i=0; i<w; i++)
      delete [] dane[i];
 
    delete [] dane; 
0
for( int i = 0 ; i < w ; i++ )
{
    delete[] dane[i]; //usuwasz tablice wewnatrz macierzy
}
delete[] dane; //usuwasz całą macierz

1 użytkowników online, w tym zalogowanych: 0, gości: 1