wskaźnik na tablice dwuwymiarową

0

Witam
Do tej pory jak chciałem zalokować 2 wymiarową tablice to robiło się to tak:

const int n=5;
const int m=2;
int **array = new int*[n];
for(int i=0; i<m; ++i)
    array[i] = new int [m];
...
for(int i=0; i<m; ++i)
    delete [] array[i];
delete []array;
array = NULL;

Spotkałem się natomiast z takim czymś (akurat tutaj przykład z mallociem, ale analogicznie można i z new):

const int n=5;
const int m=2;
int (*array)[n][m] = (int (*)[n][m])malloc(sizeof(int)*m*n);

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j)
        {
            (*array)[i][j] = i + j;
            std::cout << (*array)[i][j] << std::endl;
        }

    free(array);

Co to jest typ int (*array)[n][m]? Czy to jest wskaźnik na obszar pamięci n x m int-ów? Chyba nie bo dałem radę zalokować więcej niż "n" intów:

int (*array)[n][m] = (int (*)[n][m])malloc(sizeof(int)*m*(n+1));

i potem sie odwołać do wszystkich komórek pamięci i sie skompilowało i działało w runtimie. Więc może ten typ to wskaźnik na obszar pamięci n x m int-ów, ale taki powiedzmy "unsafe", czyli że tak czy siak możesz więcej tam zalokować niż n x m.

1

Jeżeli to ma być C++ - a tak jest, wnioskując po new - to używaj std::vector.
drugi kod dotyczy alokacji w C i używanie tego w C++ jest mocno passe - jeszcze gorzej niż używanie new.

Odsyłam do bloga Pana moderatora @kq

0

Ten drugi sposób korzysta z właściwości tablic - kolejne elementy (a w przypadku tablicy n-wymiarowej, tablica n-1 wymiarowa jest elementem) są ułożone kolejno w pamięci. Teoretycznie można tam się doszukiwać UB ze względu na niezgodność typów, ale nie znam implementacji, na której to nie działa.

Ale polecam lekturę:
https://dsp.krzaq.cc/post/176/ucze-sie-cxx-kiedy-uzywac-new-i-delete/
https://dsp.krzaq.cc/post/98/prosty-widok-na-macierz-2d-w-cpp/

0
int **array = new int*[n];
for(int i=0; i<m; ++i)
    array[i] = new int [m];

array jest tu wskaźnikiem na tablicę wskaźników.

powyższa pętla for jest błędna, bo alokowane jest miejsce na n elementów tablicy array, a pętla zawiera warunek i<m zamiast i<n.

gdyby pętla była prawidłowa, tablica array zawierałaby n wskaźników "wierszy" na m-elementowe tablice intów.

int (*array)[n][m] = (int (*)[n][m])malloc(sizeof(int)*m*n);

array jest tu tablicą n tablic po m intów. n*m intów zajmuje ciągły obszar pamięci.

int (*array)[n][m] = (int (*)[n][m])malloc(sizeof(int)*m*(n+1));

malloc zwraca void* wskazujący na przydzieloną pamięć - co z tą pamięcią potem zrobisz to nie sprawa malloca. Przydzielasz pamięci więcej niż będzie ci potrzebne i dziwisz się że nic się nie stało.

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