Dynamiczne alokowanie tablicy dwuwymiarowej, który sposób poprawny?

0

Witam, mam taki kod do dynamicznego alokowania tablicy dwuwymiarowej:

     char **tab;
    char k = 12;
    tab = malloc(3 * sizeof(int *));
    for (int i = 0; i < 3; i++) {
        *(tab + i) = malloc(4 * sizeof (int));
        for (int j = 0; j < 4; j++) {
            *(*(tab + i) + j) = k--;
        }
    }

Działa poprawnie, lecz trapi mnie pytanie dlaczego taki przykład też działa?

     char **tab;
    char k = 12;

    // zamiast int * zwykły int

    tab = malloc(3 * sizeof(int));
    for (int i = 0; i < 3; i++) {
        *(tab + i) = malloc(4 * sizeof (int));
        for (int j = 0; j < 4; j++) {
            *(*(tab + i) + j) = k--;
        }
    }

Skoro "pierwszy poziom" tablicy (wskaźnika) zawiera wskaźnik na drugi poziom to wg mnie powinno być int *. Tymczasem działają obydwa przykłady. Może ktoś sprostować?

0

W sumie żaden, bo alokujesz inty, a używasz char**. Na większości 32-bitowych architektur int ma tę samą wielkość co wskaźnik, więc sizeof(int) == sizeof(int*). W przypadku architektur 64-bitowych z reguły int ma wciąż 32 bity, ale również z reguły nieznaczne wyjście poza zakres zaalokowanej pamięci nie jest karane.

0

Z tego co pamiętam trzymanie int* w char** to ub wolno tylko wsadzać co się zapragnie w void*.
Następnie trzymac to w void**.

Stąd śmierdzi mi alokowanie int* pod char**.

To że działą nie znaczy, że jest dobrze. jak dla mnie oba są źle.

Pozdrawiam.

0

No dobra, a co w takim przypadku (też działa poprawnie)

    char **tab;
    char k = 12;
    tab = malloc(3 * sizeof(char));
    for (int i = 0; i < 3; i++) {
        *(tab + i) = malloc(4 * sizeof (char));
        for (int j = 0; j < 4; j++) {
            *(*(tab + i) + j) = k--;
        }
    }
 

Wygląda na to że kompilator (lub coś innego) samo zmienia na 8 bajtów, bo co bym tam nie wpisał zawsze jest taki sam efekt.

0

kod który dawałem tu do innej odpowiedzi:
http://ideone.com/JpHCAT

0

Mój fail tu:

    char **tab;
    char k = 12;
    tab = malloc(3 * sizeof(char*));  // char* nie char  inaczej nie masz pamięci i segfault.
    for (int i = 0; i < 3; i++) {
        (*tab + i) = malloc(4 * sizeof (char));  // *tab nie *(tab+i)  bo przez to wskakujesz na kolejną pozycję za tab** czyli segfault. 
        for (int j = 0; j < 4; j++) {
            tab[i][j] = k--;  // teraz ok. idziemy do tab[i] co jest tożsame z *tab + i  następnie idziemy na pozycję j 
        }
    }
 

poprawnie

    char **tab;
    char k = 12;
    tab = malloc(3 * sizeof(char*));  // char* nie char  inaczej nie masz pamięci i segfault.
    for (int i = 0; i < 3; i++) {
        tab[i] = malloc(4 * sizeof (char));  // przejrzystsza forma 
        for (int j = 0; j < 4; j++) {
            tab[i][j] = k--;  //podobnie jak wcześniej.
    }
 
0

Dobra też się tam jebnąłem na górze. Musze koledze zwrócić honor. forma *( tab + i ) jets poprawna.
Ale lepiej pisac tab[i] bo to jest przejrzystsze.

poprawiłęm żeby źle nie wisiało.

Starszny chaos zrobiłem w tym wątku ;-)

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