R. 44. Różne działanie w programu w zależności od początkowej wielkości tablicy. Skąd zależność?
Ostatnio zmodyfikowano 2020-03-21 20:10
mokakua Temat założony przez niniejszego użytkownika |
R. 44. Różne działanie w programu w zależności od początkowej wielkości tablicy. Skąd zależność? » 2020-03-18 23:55:09 Cześć, nie rozumiem dlaczego w zależności od początkowej wartości zmiennej rozmiar program zachowuje się inaczej.Program sprawdzałem dla kilku - kilkunastu liczb. Przykłady dla różnych wartości zmiennej: 0, 1, 2 - program działa ok; 3, 4 - do pięciu podanych liczb działa ok, gdy podam więcej liczb pierwsze 8 pokazuje randomowych, kolejne są ok; 5, 6 - jeśli podam do 8 liczb to jest ok, powyżej się wysypuje; 10, 20, 50 - źle wyświetla tylko pierwsze 2 liczby; Czy możecie mi wytłumaczyć przyczynę takiego zachowania? #include <iostream>
using namespace std;
int main() { int rozmiar = 0; int pozycja = 0; int * tablica = NULL; int * nowa = new int[ rozmiar ]; cout << "Podawaj liczby, 0 zatrzymuje proces: " << endl; while( true ) { int liczba; cin >> liczba; if( liczba == 0 ) break; if( pozycja == rozmiar ) { int * nowa = new int[ rozmiar + 10 ]; rozmiar += 10; for( int i = 0; i < pozycja; i++ ) nowa[ i ] = tablica[ i ]; } nowa[ pozycja ] = liczba; delete[] tablica; tablica = nowa; pozycja++; } cout << "Tablica: " << endl; for( int i = 0; i < pozycja; i++ ) cout << tablica[ i ] << ' '; delete[] tablica; return 0; } |
|
pekfos |
» 2020-03-19 00:10:50 Program jest błędny. Gdyby zarezerować miejsce w tablicy na wszystkie elementy z góry, program sprowadza się do while( true ) { int liczba; cin >> liczba; if( liczba == 0 ) break; nowa[ pozycja ] = liczba; delete[] tablica; tablica = nowa; pozycja++; } a więc wielokrotnie zwalniasz tą samą tablicę. |
|
mokakua Temat założony przez niniejszego użytkownika |
Poprawka? » 2020-03-19 23:52:15 To było pomocne, dzięki. Teraz zwalniam pamięć tylko przed przypisaniem wskaźnikowi tablica pierwszego adresu zarezerwowanej pamięci. Po tym jak sprawdziłem wnioskuję, że działa. Chciałem jednak wrzucić operację zwiększenia pamięci do funkcji. Funkcja jest w poniższym kodzie wykomentowana. Nie działa. Problem pojawia się, gdy ma dojść do skopiowania wartości z drugiego elementu tablicy pobranej do funkcji. Myślę, że źle używam wyłuskania. Rozumiem to tak: Jako argumentu funkcji w main() użyję adresu do wskaźnika pierwszego adresu z poprzedniej "nowej" tablicy. Muszę zatem użyć w funkcji, jako pierwszego argumentu, tablicy zmiennych wskaźnikowych. Robię t przez int *tab[]. Reszta opisana w kodzie. Proszę o punktowanie błędów w rozumowaniu i wskazówki, na czym powinienem się skupić. A może nie poznałem jeszcze jakiegoś narzędzia? #include <iostream>
using namespace std;
void wypiszTablice( int tab[], int doPozycji ) { cout << "Elementy tablicy: " << endl; for( int i = 0; i < doPozycji; i++ ) cout << tab[ i ] << ' '; }
int main() { int rozmiar = 0; int pozycja = 0; int * tablica = NULL; cout << "Podawaj liczby, 0 zatrzymuje proces: " << endl; while( true ) { int liczba; cin >> liczba; if( liczba == 0 ) break; if( pozycja == rozmiar ) { int * nowa = new int[ rozmiar + 5 ]; rozmiar += 5; for( int i = 0; i < pozycja; i++ ) nowa[ i ] = tablica[ i ]; delete[] tablica; tablica = nowa; } tablica[ pozycja ] = liczba; pozycja++; } wypiszTablice( tablica, pozycja ); delete[] tablica; return 0; } |
|
pekfos |
» 2020-03-20 00:27:43 |
|
mokakua Temat założony przez niniejszego użytkownika |
» 2020-03-20 22:27:03 Okej, dziękuję. Nie potrafię dojść do rozwiązania przez referencję. Napisałem te dwie funkcje. Jedna jest taka jak poleciłeś - uwzględnia priorytet operatorów. Wykomentowana funkcja powstała w sumie przypadkiem przy próbie wykorzystania referencji do tablicy z main(). Na chwilę mnie olśniło i dopisałem operator * przed ampersandą - wygląda jakby działało, choć nie jestem przekonany. Widzę to tak: Chcę mieć referencję do wskaźnika z głównej funkcji main() - powinien to być zatem zapis int &tab. Pracowałbym wtedy na adresach z tablicy tab. Ale ta zmienna nie jest widziana przez funkcję jako wskaźnik, a takiego oczekują komendy z funkcji powiekszTablice. Próbowałem wrzucić wskaźnik gdzieś pomiędzy "&" i "tab" , bo to wydawało mi się słuszne, ale to nie wychodzi. Na sam koniec spróbowałem w ten sposób, ale nie jestem pewny czy działa to poprawnie. Wg mnie to jest wskaźnik do tablicy wskaźników na których chcę pracować, a nie te właściwe wskaźniki. Wypisałem sobie adresy w funkcji i poza nią i wyglądają ok. Nie wiem jednak jak. #include <iostream>
using namespace std;
void wypiszTablice( int tab[], int doPozycji ) { cout << "Elementy tablicy: " << endl; for( int i = 0; i < doPozycji; i++ ) cout << tab[ i ] << ' '; }
void powiekszTablice( int * tab[], int & rozmiar, int nrPoz ) { int * nowa = new int[ rozmiar + 2 ]; rozmiar += 2; for( int i = 0; i < nrPoz; i++ ) nowa[ i ] =( * tab )[ i ]; delete[] * tab; * tab = nowa; }
int main() { int rozmiar = 0; int pozycja = 0; int * tablica = nullptr; cout << "Podawaj liczby, 0 zatrzymuje proces: " << endl; while( true ) { int liczba; cin >> liczba; if( liczba == 0 ) break; if( pozycja == rozmiar ) powiekszTablice( & tablica, rozmiar, pozycja ); tablica[ pozycja ] = liczba; pozycja++; } wypiszTablice( tablica, pozycja ); delete[] tablica; return 0; } |
|
pekfos |
» 2020-03-20 22:37:39 T& = referencja na T. Referencja na T=int* to więc po prostu int*&. Wg mnie to jest wskaźnik do tablicy wskaźników na których chcę pracować, a nie te właściwe wskaźniki. |
Jaka tablica wskaźników? To? Każda zmienna jest jednoelementową tablicą, jeśli naprawdę tego chcesz. Zapis [] w argumentach funkcji jest dość głupi, bo nie oznacza wcale tablicy. Jest to równoznaczne z int**, więc przez wskaźnik przekazujesz to, co chcesz zmodyfikować z funkcji, czyli wskaźnik na tablicę liczb do powiększenia. |
|
mokakua Temat założony przez niniejszego użytkownika |
» 2020-03-21 20:10:01 O! Dzięki, to było kluczowe. Po prostu źle czytam kod. Wiążę * i & z nazwą zmiennej a nie typem. Deklaracje powinienem czytać od prawej do lewej. W sumie pisałeś o tym w lekcji o wskaźnikach. Wg mnie to jest wskaźnik do tablicy wskaźników na których chcę pracować, a nie te właściwe wskaźniki. |
Chodziło mi o to: Ale już nieistotne. Ok, czyli podsumowując: int A int & B = A int * C * C & D int * & E int & * F
|
|
« 1 » |