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

Dwuwymiarowa tablica dynamiczna - problem z przekazaniem do funkcji

Object Storage Arubacloud
0 głosów
146 wizyt
pytanie zadane 27 listopada 2022 w C i C++ przez Noizz00 Użytkownik (910 p.)
edycja 27 listopada 2022 przez Noizz00

Edit. N to stała symboliczna, zdefiniowana przed wszystkimi funkcjami. Spróbowałem zmodyfikować nagłówek funkcji na Losuj(int **A, int rozmiar1, int rozmiar2) i odpowiednio ją zmodyfikować, jednak to nie pomaga.

Witam,

poniższy fragment funkcji dla przypadku po wprowadzeniu znaku '6' powinien zaalokować dynamicznie tablicę dwuwymiarową tab[rozmiar1][rozmiar2]. Następnie powinien wypełnić ją wartościami losowymi wskazanymi przez użytkownika (od p do k) i wyświetlić. Problem jest z tym, że nie mogę przejść do kompilacji programu - wyskakuje mi okno "It seems that this file has not been built yet". Bez poniższego fragmentu kodu program działa.

case '6':
            cout << "Podaj ilosc wierszy: ";
            cin >> rozmiar1;
            cout << "Podaj ilosc kolumn: ";
            cin >> rozmiar2;
            int **tab = new int*[rozmiar1];
            for(int i = 0; i < rozmiar1; i++)
                tab[i] = new int[rozmiar2];
            do
            {
                cout << "Podaj najmniejsza wartosc w tablicy do wylosowania: ";
                cin >> p;
                cout << "Podaj najwieksza wartosc w tablicy do wylosowania: ";
                cin >> k;
                if(p > k) cout << "Blad - wartosc najmniejsza wieksza od najwiekszej! Wprowadz wartosci ponownie." << endl;
            }while(p > k);
            Losuj(**tab, p, k);
            cout << "Tablica zaalokowana dynamicznie ma postac: " << endl;
            Wypisz(**tab);
            for(int i = 0; i < rozmiar1; i++)
                delete [] tab[i];
            delete [] tab;
            cin.ignore();
            cout << "Wcisnij ENTER, aby przejsc dalej.";
            getchar();  
break; 

Funkcja Losuj() ma postać:

void Losuj(int A[N][N], int p, int k)
{
    for(int i = 0; i < N; i++)
        for(int j = 0; j < N; j++)
            A[i][j] = rand()%(k-p+1)+p;
}

ktoś wie, w czym może leżeć problem?

2
komentarz 27 listopada 2022 przez Oscar Nałogowiec (29,320 p.)
edycja 27 listopada 2022 przez Oscar
W swoim kodzie allokujesz najpierw zwykłą jednowymiarową tablice wskaźników na int (rozmiar 1), a potem do każdego elementy tej tablicy allokujesz tablicę intów (rozmiar 2). Nie jest to typowa, jednorodna tablica, zajmująca spójny obszar pamięci, a szereg mniejszych tablic, stanowiących poszczególne wiersze tej "wirtualnej" tablicy. To jest w porządku, tak też można robić. Jednak w C jak przekazujesz tablicę to wołana funkcja nie ma pojęcia o rozmiarze tablicy, przekazywany jest jedynie wskaźnik na pierwszy element. O przekazanie rozmiatu musisz zadbać sam.

Natomiast taka definicja funkcji Losuj zakłada że funkcja ta otrzyma jako parametr wskaźnik na pierwszy element tablicy kwadratowej, taki spójny obszar pamięci NxN - bez tej pośredniej tablicy wskaźników. W takim przypadku adresowanie będzie polegało na obliczeniu 'numeru' elementu z wyrażenia postaci N*y+x, a potrzebujesz dwuetapowego adresowania - najpierw w tablicy wskaźników a potem w wybranej tablicy danego wiersza.

int A[N][N] - to dane jednorodną, spójną tablicę dwuwymiarową.

int * A[N] lub int **A - to jest tablica wskaźników

 

Natomiast jeśli chodzi o kompilację twojego kodu - to do funkcji przekazuje się wskaźnik, tylko dla ułatwienia nazwa tablicy oznacza w takim kontekście wskaźnik na pierwszy element. Taka próba 'wyłuskania' tablicy **t będzie oznaczała po prostu przekazanie pierwszego elementu - czyli int-a.
1
komentarz 27 listopada 2022 przez VBService Ekspert (254,490 p.)
1
komentarz 27 listopada 2022 przez TOWaD Mądrala (6,000 p.)

Dokładnie, tak w linku  @VBService, owiń klasą. To co napisał @Oscar to prawda i da się dwuwymiarowo, coś takiego zrobić, ale to jest proszenie się o kłopoty i błąd naruszenia pamięci, co nie omieszkałem uczynić próbując to odkodować w ten sposób;

void Losuj(int A[][rozmiar2],int rozmiar1, int p, int k) //tylko w takim przypadku może uda Ci się wywołać funkcję; Ale rozmiar2 musi być const;

A tu spłaszczony problem i nie ma problemu tablicy dwuwymiarowej;

I dlaczego nie std::vector ?

1
komentarz 28 listopada 2022 przez Noizz00 Użytkownik (910 p.)
@TOWaD, jeszcze nie poznałem wektorów i dlatego z nich nie skorzystałem w tym zadaniu, ale czytałem, że w tym przypadku ich użycie byłoby dobrym rozwiązaniem. @VBService, dzięki za linka, a @Oscar, dzięki za wyjaśnienia :)

Zaloguj lub zarejestruj się, aby odpowiedzieć na to pytanie.

Podobne pytania

0 głosów
0 odpowiedzi 128 wizyt
pytanie zadane 28 stycznia 2022 w C i C++ przez danielch Użytkownik (660 p.)
0 głosów
1 odpowiedź 209 wizyt
pytanie zadane 19 kwietnia 2020 w C i C++ przez julsonem Nowicjusz (120 p.)
0 głosów
1 odpowiedź 606 wizyt

92,655 zapytań

141,545 odpowiedzi

319,979 komentarzy

62,024 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...