• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zapisywanie do struktury

VPS Starter Arubacloud
0 głosów
535 wizyt
pytanie zadane 28 grudnia 2017 w C i C++ przez lambdag Obywatel (1,310 p.)

Witam ponownie,

struct map{
    int x;
    int y;
    int **flat;
};
struct map* wczytaj(struct map *mapa1)
{
    int i,j;
    mapa1->flat = (int*) malloc(sizeof(int)* mapa1->x);
    for(i = 0; i < mapa1->x; i++)
    {
        mapa1->flat = (int*) malloc(sizeof(int)* mapa1->y);
        for(i = 0; i < mapa1->y; i++)
        {
            printf("enter:");
            scanf("%d", &(mapa1->flat[i][j]));
        }
    }

};
struct map* sum(struct map *mapa1, struct map *mapa2)
{
    int i,j;
   struct map* newxmap;
   newxmap = (struct map*) malloc(sizeof(struct map));
    newxmap->x = mapa1->x;
    newxmap->y = mapa1->y;
    if(mapa1->x != mapa2->x || mapa1->y != mapa2->y)
    {
        printf("Twoja macierz nie tych samych wielkosci");
    }
    for(i = 0; i < newxmap->x; i++)
    {
        for(j = 0; j < newxmap->y; j++)
        {
         newxmap->flat[i][j] = mapa1->flat[i][j] + mapa2->flat[i][j];
        }
    }
    return newxmap;
}
int main()
{
    struct map macierz1;
    struct map macierz2;
    struct map *newxmap;
    my.x = 3;
    my.y = 3;
    towrite(&macierz1);
    return 0;
}

Ogólnie zarys miał wyglądać tak, tworze sobie 2 struktury na 2 macierze, z góry podaje wielkość tych macierzy podałem że 3x3 czyli tablica dwuelementowa 3x3, zrobiłem to co trzeba ale chyba, ba napewno zle alokuje pamięć dla tych macierzy w funkcji wczytaj, ogólnie na czuje robie alokacje dynamiczna dla tablic dwuwymiarowych. Proszę o pomoc, program się sypie gdy chce wpisać 4 element do tablicy to jakby flat[1][0] ...

1 odpowiedź

+1 głos
odpowiedź 28 grudnia 2017 przez Arkadiusz Sikorski Pasjonat (20,160 p.)

strzałki pokazujące błędy w kodzie
Tu nie ma nic do robienia na czuja; popatrz na obrazek powyżej powyżej.

  • 1. strzałka - do zmiennej typu int** próbujesz zapisać wskaźnik typu int*. Ponadto próbujesz zaalokować blok pamięci o wielkości sizeof(int), a chcesz alokować blok wskaźników na int, czyli (int*).
  • 2. strzałka - ponownie alokujesz pamięć i przypisujesz do już zaalokowanej zmiennej. To, co chcesz zrobić, to zapisać zaalokowany blok intów do indeksu tablicy flat - musisz więc użyć operatora [], żeby odwołać się do i-tego wskaźnika i do niego przypisać odpowiednią wartość.
  • Podkreślenie - twoją zmienną iterującą w wewnętrznej pętli jest i zamiast j.

To tylko słowa; więcej powie zmieniona funkcja wczytaj. Oto ona:

struct map* wczytaj(struct map *mapa1)
{
    int i,j;
    mapa1->flat = (int**) malloc(sizeof(int*) * mapa1->x); // alokujemy tablice wskaznikow na inty
    for(i = 0; i < mapa1->x; i++) 
    {
        mapa1->flat[i] = (int*) malloc(sizeof(int) * mapa1->y); // kazdy i-ty element to wskaznik na tablice intow
        for(j = 0; j < mapa1->y; j++)
        {
            printf("enter:");
            scanf("%d", mapa1->flat[i] + j); 
            /*  
                mapa1->flat[i] to wskaznik, 
                dodanie j oznacza odwołanie się do adresu j-tego elementu
                taki trick ulatwiajacy czytanie kodu
            */
        }
    }
}

 

komentarz 28 grudnia 2017 przez lambdag Obywatel (1,310 p.)

Ok teraz mam pytanie napisałem tak ale funkcja sum nie działa, próbowałem dodać alokacje ale wtedy nie działa poprawnie...


struct map{
    int x;
    int y;
    int **flat;
};
struct map* wczytaj(struct map *mapa1)
{
    int i,j;
    mapa1->flat = (int**) malloc(sizeof(int*) * mapa1->x);
    for(i = 0; i < mapa1->x; i++)
    {
        mapa1->flat[i] = (int*) malloc(sizeof(int) * mapa1->y);
        for(j = 0; j < mapa1->y; j++)
        {
            printf("enter:");
            //scanf("%d", &(mapa1->flat[i][j]));
            scanf("%d", mapa1->flat[i] + j);
        }
    }

}
struct map* sum(struct map *mapa1, struct map *mapa2)
{
    int i,j;
   struct map* newxmap;
   newxmap = (struct map*) malloc(sizeof(struct map));
    newxmap->x = mapa1->x;
    newxmap->y = mapa1->y;
    if(mapa1->x != mapa2->x || mapa1->y != mapa2->y)
    {
        printf("Twoja macierz nie tych samych wielkosci");
    }
   // newxmap->flat = (int**) malloc(sizeof(int*) * newxmap->x);
    for(i = 0; i < newxmap->x; i++)
    {
        // newxmap->flat[i] = (int*) malloc(sizeof(int) * newxmap->y);
        for(j = 0; j < newxmap->y; j++)
        {
         newxmap->flat[i][j] = mapa1->flat[i][j] + mapa2->flat[i][j];
        }
    }
    return newxmap;
}
struct map print(struct map *map)
{
    int i,j;
    for(i = 0; i < map->x; i++) {
        for(j = 0; j < map->y; j++)
        {
            printf("%d", map->flat[i][j]);
        }
        printf("\n");
    }



}
int main()
{
    struct map macierz1;
    struct map macierz2;
    struct map *newxmap;
    macierz1.x = 3;
    macierz1.y = 3;
    macierz2.x = 3;
    macierz2.y = 3;
    /*Wczytywanie*/
    wczytaj(&macierz1);
    printf("\n");
    wczytaj(&macierz2);
    /*--------------*/
    newxmap = sum(&macierz1, &macierz2);
    print(&newxmap);
    return 0;
}

I ona działa sprawdzałem

komentarz 28 grudnia 2017 przez Arkadiusz Sikorski Pasjonat (20,160 p.)
To powyżej na pewno nie zadziała - jeżeli tworzysz nową tablicę, to musisz ją zaalokować identycznie jak w funkcji wczytaj. Odkomentuj alokacje. Ponadto w funkcji main wywołujesz printa z &newxmap jako argumentem, a powinno być po prostu newxmap (newxmap już jest wskaźnikiem, nie potrzeba Ci jego adresu, żeby przekazać tę macierz do funkcji print).
komentarz 28 grudnia 2017 przez lambdag Obywatel (1,310 p.)
Dzięki! Działa ;) czyli tak newxmap = (struct map*) malloc(sizeof(struct map)); robię to dlatego że kompilator nie wie jaka ta struktura musi mieć pamięć. a tablica **flat i tak swoją drogą też trzeba alokować.. Ok dobrze to rozumiem?
komentarz 28 grudnia 2017 przez Arkadiusz Sikorski Pasjonat (20,160 p.)
edycja 28 grudnia 2017 przez Arkadiusz Sikorski
Kompilator zawsze będzie wiedział jaki rozmiar ma zmienna typu struct map - będzie to sizeof(int) + sizeof(int) + sizeof(int**). To może być zaskakujące, ale blok pamięci wskazywany przez flat fizycznie nie należy do struktury - należy do niej tylko wskaźnik pokazujący na ten blok pamięci i dwa inty oznaczające wymiary. Skutkuje to tym, że struktura map będzie miała stały rozmiar (u mnie jest to przykładowo 4 + 4 + 8 = 16). Oczywiście struktura logicznie, jako całość, nadal zajmuje w pamięci 2*sizeof(int) + sizeof(int**) + x*y*sizeof(int).

No i nie musisz alokować mapy. Równie dobrze mógłbyś w funkcji sum zwracać strukturę zamiast wskaźnika na strukturę, wtedy alokowałbyś odpowiednio tablicę tablic (zmienna flat), przypisywał ją do lokalnej zmiennej typu map, do tej samej zmiennej przypisywał wymiary, a następnie zwracał tę strukturę.

W skrócie: alokować musisz tylko zmienną flat, a całej mapy już nie - wszystko zależy od tego, co przyjmiesz jako typ zwracany.

Podobne pytania

0 głosów
2 odpowiedzi 807 wizyt
0 głosów
0 odpowiedzi 495 wizyt
pytanie zadane 23 kwietnia 2021 w C i C++ przez Mavimix Dyskutant (8,390 p.)
0 głosów
1 odpowiedź 341 wizyt
pytanie zadane 20 września 2020 w C i C++ przez magda_19 Gaduła (3,080 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...