pieter111 Temat założony przez niniejszego użytkownika |
Funkcja kasująca listę jednokierunkową [C++]. Prośba o sprawdzenie. » 2017-06-09 09:51:00 Witam, sprawa dotyczy funkcji kasującej listę jednokierunkową. Gdzieś jest błąd bo kasuje tylko pierwszy element z listy, jakby Ktoś mógł zerknąć na poniższy kod z góry dzięki. void skasuj( lista * adres ) { lista * poprzedni, * aktualny, * temp; poprzedni = adres; aktualny = adres; while( adres != NULL ) { if( aktualny == adres ) { temp = adres; adres = adres->wsk_nastepnika; delete temp; } else { poprzedni->wsk_nastepnika = aktualny->wsk_nastepnika; temp = aktualny; aktualny = aktualny->wsk_nastepnika; delete temp; } } }
|
|
ArgonZapan |
» 2017-06-09 10:51:59 aktualny = adres; a za chwilę if( aktualny == adres ) jak wygląda, deklaracja typu lista ? Nie jestem pewien czy to będzie działać:) if { adres != nulltptr ) { while( adres->nastepnika != nullptr ) { temp = adres; adres = adres > nastepnika; delete temp; } delete adres; }
|
|
pieter111 Temat założony przez niniejszego użytkownika |
» 2017-06-09 11:17:13 Deklaracja typu lista, też tak próbowałem jak Ty, ale kasuje tylko pierwszy element z węzła pierwszego i reszta pozostaje bez zmian, nawet pierwszy węzeł. |
|
ArgonZapan |
» 2017-06-09 11:24:31 void skasuj( lista * adres ) { lista * temp; if { adres != nulltptr ) { while( adres->nastepnika != nullptr ) { temp = adres; adres = adres->nastepnika; delete temp; } delete adres; } }
Teraz zauważyłem że uciekł mi myślnik :P A tak jak jest teraz działa? |
|
pieter111 Temat założony przez niniejszego użytkownika |
» 2017-06-09 11:41:01 Też nie działa, sytuacja bez zmian, dzięki za podpowiedzi. |
|
ArgonZapan |
» 2017-06-09 11:53:50 Pokaż więcej kodu |
|
pieter111 Temat założony przez niniejszego użytkownika |
» 2017-06-09 12:16:55 Zadanie: wprowadzic n figur z ilością boków, polem powierzchni i nazwą. Skasować co drugą figurę której liczba boków jest większa od trzech i dopisać jedną figurę na końcu listy. Na koniec skasować listę funkcją kasującą tą listę. I tu jest właśnie problem. @ArgonZapan jak masz chwilę spróbuj skompilować na swoim kompie, ja to kompilowałem w codeblocks. #include <iostream> #include <limits> #include <string> #include <cstdlib>
using namespace std; const int n = 2; struct lista { string nazwa; double pole_pow; int ile_bokow; lista * wsk_nastepnika; }; void drukuj( lista * adres ) { cout << "Zawartosc listy:\n"; while( adres != NULL ) { cout << adres->nazwa << " " << adres->ile_bokow << " " << adres->pole_pow; adres = adres->wsk_nastepnika; cout << endl; } }
void skasuj( lista * adres ) { lista * temp, * aktualny; aktualny = adres; while( adres != NULL ) { if( aktualny == adres ) { temp = adres; adres = adres->wsk_nastepnika; delete temp; } else { temp = aktualny; aktualny = aktualny->wsk_nastepnika; delete temp; } } }
int main() { lista * glowa, * aktualny, * poprzedni, * ogon; bool fail, fail1; glowa = new lista; int i = 0; do { cout << "Nazwa? "; cin >> glowa->nazwa; while( glowa->nazwa[ i ] ) { if( isalpha( glowa->nazwa[ i ] ) ) fail1 = false; else { fail1 = true; cout << "Nieprawidlowa nazwa, wprowadz nazwe skladajaca sie z samych liter. "; break; } i++; } } while( fail1 == true ); do { cout << "Ile bokow? "; cin >> glowa->ile_bokow; fail = cin.fail(); if( fail == true ) { cout << "Liczba bokow musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); do { cout << "Powierzchnia?"; cin >> glowa->pole_pow; fail = cin.fail(); if( fail == true ) { cout << "Pole powierzchni musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); glowa->wsk_nastepnika = NULL; ogon = glowa; for( int i = 1; i < n; i++ ) { aktualny = new lista; do { cout << "Nazwa? "; cin >> aktualny->nazwa; while( aktualny->nazwa[ i ] ) { if( isalpha( aktualny->nazwa[ i ] ) ) fail1 = false; else { fail1 = true; cout << "Nieprawidlowa nazwa, wprowadz nazwe skladajaca sie z samych liter. "; break; } i++; } } while( fail1 == true ); do { cout << "Ile bokow? "; cin >> aktualny->ile_bokow; fail = cin.fail(); if( fail == true ) { cout << "Liczba bokow musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); do { cout << "Powierzchnia? "; cin >> aktualny->pole_pow; fail = cin.fail(); if( fail == true ) { cout << "Pole powierzchni musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); aktualny->wsk_nastepnika = NULL; ogon->wsk_nastepnika = aktualny; ogon = aktualny; } drukuj( glowa ); cout << endl; lista * tmp, * nowy; int l = 0; aktualny = glowa; poprzedni = glowa; while( aktualny != NULL ) { if( aktualny->ile_bokow > 3 ) { if( aktualny == glowa ) { l++; poprzedni = aktualny; aktualny = aktualny->wsk_nastepnika; } else { l++; if( l == 2 ) { poprzedni->wsk_nastepnika = aktualny->wsk_nastepnika; tmp = aktualny; aktualny = aktualny->wsk_nastepnika; delete tmp; l = 0; nowy = new lista; cout << "Nazwa? "; cin >> nowy->nazwa; do { cout << "Nazwa? "; cin >> nowy->nazwa; while( nowy->nazwa[ i ] ) { if( isalpha( nowy->nazwa[ i ] ) ) fail1 = false; else { fail1 = true; cout << "Nieprawidlowa nazwa, wprowadz nazwe skladajaca sie z samych liter. "; } i++; } } while( fail1 == true ); do { cout << "Ile bokow? "; cin >> nowy->ile_bokow; fail = cin.fail(); if( fail == true ) { cout << "Liczba bokow musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); do { cout << "Powierzchnia? "; cin >> nowy->pole_pow; fail = cin.fail(); if( fail == true ) { cout << "Pole powierzchni musi byc liczba, wprowadz liczbe.\n"; } cin.clear(); cin.ignore( numeric_limits < streamsize >::max(), '\n' ); } while( fail == true ); nowy->wsk_nastepnika = NULL; ogon->wsk_nastepnika = nowy; } else { poprzedni = aktualny; aktualny = aktualny->wsk_nastepnika; } } } else { poprzedni = aktualny; aktualny = aktualny->wsk_nastepnika; } } drukuj( glowa ); skasuj( glowa ); cout << endl; drukuj( glowa ); return 0; }
|
|
ArgonZapan |
» 2017-06-09 13:41:20 void drukuj( lista * adres ) { cout << "Zawartosc listy: \n"; while( adres != NULL ) { cout << adres->nazwa << " " << adres->ile_bokow << " " << adres->pole_pow; adres = adres->wsk_nastepnika; cout << endl; } }
void skasuj( lista * & adres ) { lista * temp; if( adres != nullptr ) { while( adres->wsk_nastepnika != nullptr ) { temp = adres; adres = adres->wsk_nastepnika; delete temp; temp = nullptr; } delete adres; adres = nullptr; } }
Jeśli użyjesz delete do wskaźnika, usuwa on zawartość tego na co wskazuje. Lecz dalej wskazuje on na jakąś komórkę w pamięci. Dlatego używamy nullptr, by nadać mu wartość zerową. W funkcji "drukuj", przyrównywałeś do zera, ale wskaźnik wciąż wskazywał, na jakąś komórkę. Więc program się sypał w tamtym miejscu, gdy chciałeś się odwołać do skasowanej komórki. W dodatku, jeśli w funkcji argument wygląda tak lista * adres . Oznacza że operujesz na kopii wskaźnika. Dodając ampersand lista * & adres , wtedy działasz na oryginalnym wskaźniku. Pierwszy od drugiego różni się tym, że na kopii, jeśli użyjesz adres = nullptr. To po wyjściu z funckji, to co przekazałeś, dalej będzie wskazywać, tam gdzie gdzie wcześniej. Na oryginalnym wskaźniku, po wyjściu z funckji, będzie nullptr. |
|
« 1 » 2 |