dynamiczne alokowanie pamięci - [x][y] czy [y][x]

0

Cześć,
mam takie pytanie:
alokuję sobie tablicę dwu wymiarową w C++ w ten sposób:

int x = 5;
int y = 10;

    int** tablica = new int* [x];
    for (int i = 0; i < x; ++i)
        tablica[i] = new int [y];

I nurtuje mnie pytanie czy wówczas utworzy się tablica o rozmiarze: tablica[x][y] czy tablica[y][x]?
Oczywiście komórek będzie tyle samo ale nie wiem jak indexować ową tablicę :(

Drugie pytanie dot. operatora new - czy tworząc w ten sposób tablicę utworzy się ona na stosie (szybko) czy na stercie (wolno)? Gdzieś czytałem, że to zależy od kompilatora lub od wielkości tablicy i szukam potwierdzenia.
z góry dzięki za odpowiedzi.
pozdrawiam

0

Wymiary będą mieć taką kolejność w jakiej je alokujesz, u Ciebie będzie najpierw x, potem y. Alokujesz tablicę x-wskaźników. Każdy z tych wskaźników wskazuje na tablicę y-elementów.

Normalnie new alokuje na stercie. Operator ten można jednak przeciążyć i wtedy może on przydzielać pamięć w jakiś inny sposób. Dodatkowo jest jeszcze placement new.

0

No właśnie też mi się tak wydawało, ale przeczytałem uwagę ze strony http://darkcult.nazwa.pl/wiki/index.php/Kurs_C%2B%2B_cz%C4%99%C5%9B%C4%87_3 , której nie do końca rozumiem, a która brzmi tak:

Jeśli masz gdzieś w kodzie odwołanie w rodzaju tab[x][y], to prawie na pewno popełniasz błąd – powinno być tab[y][x]. Wynika to z charakterystyki operatora [] w C++ (łączność od lewej do prawej). W niektórych innych językach pisze się indeksy w odwrotnej kolejności, co wydaje nam się bardziej naturalne. W większości sytuacji taka pomyłka skutkuje tylko wolniejszym działaniem programu, ale przy odrobinie pecha konsekwencje mogą być oczywiście poważniejsze (zwłaszcza gdy liczba rzędów w tablicy jest różna od liczby kolumn).

Do tego sprawdziłem to i obie wersje działają poprawnie tj. tablica[x][y] oraz tablica[y][x] O_o -> co mnie bardzo dziwi...
I mam właśnie obawy żebym nie użył jakiejś komórki pamięci, która mi się kiedyś zmieni (a inne zostaną nieużywane)...

1

To przypadek że działają tak samo, pamięć przydziela się blokami, nawet jak przydzielisz 1 bajt to przydzieli się 4,8,16 lub 32 w zależności od kompilatora.
Spróbuj x=4,y=1024 to natychmiast wylezie szydło z worka.

To co napisano w tym artykule mówi że trzeba zrobić to tak:
int **tablica = new int *[maxy];
for(int i=0;i<maxy;++i) tablica[i]=new int [maxx];
oraz odpowiednio adresować później:
tablica[y][x]

Z tym że co jest X-em a co Y-em to jest kwestia umowna.

0

Dzięki wielkie za odpowiedzi!
Ja jakoś się przyzwyczaiłem, że najpierw podaje się X a później Y więc trochę dziwnie patrzę na taką tablicę :) (i pewnie stąd to nieporozumienie) -> ja zrobiłbym to odwrotnie :

    int **tablica = new int *[maxx];
    for(int i=0;i<maxx;++i) tablica[i]=new int [maxy];
oraz odpowiednio adresować później:
tablica[x][y]

Oczywiście to jest dokładnie to samo -> tylko pozamieniałem nazwy zmiennych :P.

0

To jest dokładnie to co napisałem, tylko pamiętaj że skoro tak zrobiłeś to masz tak jakby zbiór kolumn, a większość algorytmów rozpatruje tablicę jako zbiór wierszy. Wiec dla tego większość programistów zrobi jednak tablica[y][x] a nie odwrotnie. Jak przyzwyczaisz się do takiego odmiennego postępowania to trudnij będzie ci zrozumieć obcy kod i trudniej innym będzie zrozumieć twój.

0

A nie bezpieczniej będzie Ci użyć vectora z C++ zamiast błędotwórczej tablicy dwuwymiarowej z C?
Jego elementami powinny być vectory zawierające komórki Twojej tablicy. Odpadnie Ci wtedy ręczne zarządzanie pamięcią, na dodatek tablice takie będą mogły być nierówne (różne ilości elementów w tym samym wymiarze). Można też zdefiniować taki typ lub klasę i dorobić operatory, żeby używać tego podobnie łatwo jak tablicę dwuwymiarową.

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