Tablice wielowymiarowe, wypisanie w jednej pętli.

0

Uczę się C++. Jestem przy tablicach, mam pewien dylemat. W Gręboszu napisane jest że tablice przechowywane są "rzędami" w pamięci, jeden za drugim. Czyli tablica int [4][2] zajmuje ciągły obszar w pamięci 8*sizeof(int). W związku z tym mając wskaźnik na pierwszy element i zwiększając go 8 razy powinniśmy móc wypisać wszystkie elementy tablicy. No i jako że zmienna tablicowa jest zarazem adresem zerowego elementu chciałem to właśnie ją zwiększać. W przypadku jednowymiarowych tablic to działa:

int main(){

    int a[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};

    int *w = &a[0][0];

    for (int i = 0;i < 8;i++)std::cout << *(w++) << ' ';

    std::cout << std::endl;

    for (int i = 0;i < 8;i++)std::cout << *(*a + i) << ' ';

    getchar();
}

I nie mogę zaczaić dlaczego trzeba pisać (a + i), a jak jest trójwymiarowa tablica to trzeba pisać

*(**a + i)

, a potem *(***a + i)

. Czyli że co <code class="cpp">*a

to jest dopiero wskaźnik na pierwszą dwójkę, i to jego musimy zwiększać ?

A przy okazji jeszcze kilka głupich pytań:

Jeśli zwalniamy dynamicznie utworzoną tablicę używamy operatora </li> </ol>

delete [] zmienna;

skąd to delete wie ile ma zwolnić, skoro ponoć nie ma sposobu aby dowiedzieć się ile elementów ma tablica ?

Jak to jest że wskaźnik to nie tylko informacja o adresie ale także o typie zmiennej na którą wskazuje ? Skoro cały ma 4 bajty (ew. 8 dla x64) to gdzie ta informacja o typie się "mieści" ?</li> </ol>

b

0

Czyli że co

*a

to jest dopiero wskaźnik na pierwszą dwójkę, i to jego musimy zwiększać ?

Tak, to jest to samo co &a[0][0].

(...) skąd to delete wie ile ma zwolnić, skoro ponoć nie ma sposobu aby dowiedzieć się ile elementów ma tablica ?

Rozmiar tablicy jest zapisywany w nowo przydzielonym bloku pamięci. I owszem w przypadku pamięci przydzielonej przez new[] taką informację zapewne mógłbyś uzyskać, ale problem w tym, że posiadając jedynie wskaźnik nie wiesz, czym dana pamięć została przydzielona. Dodatkowo new[] dla typów prostych wcale nie musi takiej informacji przechowywać - info o ilości elementów tablicy jest potrzebne tylko do tego, żeby było wiadomo, ile razy trzeba wywołać destruktor. Typy proste nie posiadają destruktorów, więc informacja o ilości elementów tablicy jest zbędna.

0
0x666 napisał(a)

Rozmiar tablicy jest zapisywany w nowo przydzielonym bloku pamięci. I owszem w przypadku pamięci przydzielonej przez new[] taką informację zapewne mógłbyś uzyskać...

Ale gdzie jest zapisywany, i jak go uzyskać ?

b

0

Gdzieś przed przydzielanym (dla użytkownika) blokiem pamięci. Podejrzyj sobie w widoku asemblera jak zrealizowane jest wywołanie delete[]. Będziesz wiedział, gdzie dokładnie znajduje się informacja o wielkości tablicy. Choć nie wiem, na co Ci takie dłubanie, przecież to jest zupełnie nieprzenośne, zależne od (ustawień) kompilatora.

0
0x666 napisał(a)

Gdzieś przed przydzielanym (dla użytkownika) blokiem pamięci. Podejrzyj sobie w widoku asemblera jak zrealizowane jest wywołanie delete[]. Będziesz wiedział, gdzie dokładnie znajduje się informacja o wielkości tablicy. Choć nie wiem, na co Ci takie dłubanie, przecież to jest zupełnie nieprzenośne, zależne od (ustawień) kompilatora.

No nie jest mi jakoś specjalnie potrzebne - uczę się C++ (znam coś niecoś Delphi). Jest dla mnie zwyczajnie dziwne, że ta informacja jest niedostępna.

b

0

wydawało mi się, że system operacyjny sobie zapamiętuje ile i gdzie bloków pamięci alokował. Przecież funkcja free, które idzie w parze z mallociem posiada w parametrze tylko wskaźnik i nie ma tam żadnego rozmiaru pamięci, który ma zwolnić.

HeapAlloc
http://msdn.microsoft.com/en-[...]op/aa366597%28v=vs.85%29.aspx

HeapFree
http://msdn.microsoft.com/en-[...]op/aa366701%28v=vs.85%29.aspx

i uwaga... HeapSize
http://msdn.microsoft.com/en-[...]op/aa366706%28v=vs.85%29.aspx

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