Różnice

Różnice między wybraną wersją a wersją aktualną.

Odnośnik do tego porównania

Both sides previous revision Poprzednia wersja
Nowa wersja
Poprzednia wersja
pl:dydaktyka:jimp2:2017:labs:pamiec-i-pliki [2017/03/03 15:30]
mwp [Ale jest nadzieja - zautomatyzowane zarządzanie pamięcią część pierwsza]
pl:dydaktyka:jimp2:2017:labs:pamiec-i-pliki [2019/06/27 15:50] (aktualna)
Linia 113: Linia 113:
  
 Niestety należy pamiętać o tym by zwolnić pamięć przydzieloną inaczej uzyskujemy wyciek pamięci i program w trakcie działania zaczyna zużywać coraz więcej pamięci operacyjnej mimo, że już jej i tak nigdy nie użyje! Sprawa też nie jest taka prosta, bo nie zawsze wiadomo, czy pewne elementy nie są już na pewno przez nikogo używane. Niestety należy pamiętać o tym by zwolnić pamięć przydzieloną inaczej uzyskujemy wyciek pamięci i program w trakcie działania zaczyna zużywać coraz więcej pamięci operacyjnej mimo, że już jej i tak nigdy nie użyje! Sprawa też nie jest taka prosta, bo nie zawsze wiadomo, czy pewne elementy nie są już na pewno przez nikogo używane.
 +
 +=== Brak wartości ===
 +
 +W C%%++%%11 nie używamy już makra **NULL** zostało dodane specjalne słowo kluczowe reprezentujące pusty wskaźnik **nullptr**
 +
 +<code cpp>
 +int *v = nullptr;
 +delete v;
 +</​code>​
 +
  
 =====Ale jest nadzieja - zautomatyzowane zarządzanie pamięcią część pierwsza===== =====Ale jest nadzieja - zautomatyzowane zarządzanie pamięcią część pierwsza=====
 +
 +Jedną z możliwości automatycznego zarządzania pamięcią jest oddelegowanie tego zadania do kontenerów zdefiniowanych w bibliotece standardowej,​
 +które automatycznie zwolnią pamięć jeśli przestanie ona być używana.
 +==== Vector ====
 +
 +Jednym z takich kontenerów jest tablica rozszerzalna [[http://​en.cppreference.com/​w/​cpp/​container/​vector|vector]],​ zapoznać się z dokumentacją
 +uruchomić przykłady podane w dokumentacji przez **run code** i przyglądnąć się dokumentacji funkcji:
 +  * emplace_back
 +  * pop_back
 +  * clear
 +Przenalizować poniższy kod:
 +<code cpp>
 +#include <​iostream>​
 +#include <​vector>​
 +
 +using std::cout;
 +using std::endl;
 +using std::​vector;​
 +
 +void PrintVector(const vector<​int>​ &v) {
 +    bool first = true;
 +    for(auto n : v) {
 +        if (!first) {
 +            cout<<​ ", ";
 +        } else {
 +            first = false;
 +        }
 +        cout << n;
 +        ​
 +    }
 +    cout<<​endl;​
 +}
 + 
 +int main()
 +{
 +    // Create a vector containing integers
 +    vector<​int>​ v = {7, 5, 16, 8};
 +    ​
 +    cout << "​initilized with 4 numbers"<<​endl;​
 +    PrintVector(v);​
 + 
 +    // Add two more integers to vector
 +    v.emplace_back(25);​
 +    v.emplace_back(13);​
 +    cout << "after 2 more inserted"<<​endl;​
 +    PrintVector(v);​
 + 
 +    //copy of the value inside vector
 +    for (auto n : v) {
 +        ++n;
 +    }
 +    ​
 +    cout << "BUT: after incrementation"<<​endl;​
 +    PrintVector(v);​
 +    ​
 +    //reference to the value inside vector, therefore one can change the value
 +    for (auto &n : v) {
 +        ++n;
 +    }
 +    cout << "and again... can you spot the difference?"<<​endl;​
 +    PrintVector(v);​
 +}
 +</​code>​
 +[[http://​coliru.stacked-crooked.com/​a/​056089e192222291|Run code]]
 +
 +==== Map ====
 +
 +[[http://​en.cppreference.com/​w/​cpp/​container/​map|Tablica asocjacyjna]],​ która pozwala zaadresować dowolny element innym typem, niekoniecznie tylko liczbą naturalną.
 +
 +<code cpp>
 +#include <​iostream>​
 +#include <map>
 +
 +using std::cout;
 +using std::endl;
 +using std::map;
 +
 +void PrintMap(const map<​char,​int>​ &v) {
 +    bool first = true;
 +    for(const auto &n : v) {
 +        if (!first) {
 +            cout<<​ ", ";
 +        } else {
 +            first = false;
 +        }
 +        cout << n.first << " -> " << n.second;
 +        ​
 +    }
 +    cout<<​endl;​
 +}
 + 
 +int main()
 +{
 +    // Create a vector containing integers
 +    map<​char,​ int> v = {{'​a',​17},​ {'​c',​-2},​ {'​g',​67},​ {'​z',​13}};​
 +    ​
 +    cout << "​initilized with 4 numbers"<<​endl;​
 +    PrintMap(v);​
 + 
 +    // Add two more integers to vector
 +    v.emplace('​h',​25);​
 +    v.emplace('​$',​13);​
 +    cout << "after 2 more inserted"<<​endl;​
 +    PrintMap(v);​
 + 
 +    //copy of the value inside vector
 +    for (const auto &n : v) {
 +        //​Compilation error
 +        //​++n.second;​
 +    }
 +    ​
 +    cout << "BUT: after incrementation"<<​endl;​
 +    PrintMap(v);​
 +    ​
 +    //reference to the value inside vector, therefore one can change the value
 +    for (auto &n : v) {
 +        ++n.second;
 +    }
 +    cout << "and again... can you spot the difference?"<<​endl;​
 +    PrintMap(v);​
 +}
 +</​code>​
 +
 +[[http://​coliru.stacked-crooked.com/​a/​4d32653f8fae33c3|Run code]]
 ===== Operacje na plikach ===== ===== Operacje na plikach =====
 Operacje na plikach wykonywane są w C++ przy użyciu strumieni - analogicznie jak operacja czytania z klawiatury i wypisywania na ekran. Operacje na plikach wykonywane są w C++ przy użyciu strumieni - analogicznie jak operacja czytania z klawiatury i wypisywania na ekran.
Linia 205: Linia 339:
 ====== Ćwiczenia ====== ====== Ćwiczenia ======
   - Zrefaktoryzować kod metod //​factorial//,​ //reverse// i //​is_palindrome//​ tak, żeby nawiązywały do konwencji, że nazwa funkcji jest pisana jako //​NazwaFunkcjiCamelCase//,​ skorzystać z narzędzia do refaktoryzacji wbudowanego w CLion: najechać na metodę kursorem wybrać z menu Refactor->​Rename... (SHIFT+F6).   - Zrefaktoryzować kod metod //​factorial//,​ //reverse// i //​is_palindrome//​ tak, żeby nawiązywały do konwencji, że nazwa funkcji jest pisana jako //​NazwaFunkcjiCamelCase//,​ skorzystać z narzędzia do refaktoryzacji wbudowanego w CLion: najechać na metodę kursorem wybrać z menu Refactor->​Rename... (SHIFT+F6).
-  - [1 plus] W sekcji [[#​wskazniki_i_alokacja_pamieci|Wskaźniki i alokacja pamięci]] zostało powiedziane,​ że **nie można** utworzyć tablicy wielowymiarowej prostym poleceniem //int * *tab = new int[10][10]//​. Przeanalizuj rysunek poniżej i zastanów się dlaczego tak jest. Następnie napisz program który będzie pobierał od użytkownika wymiary tablicy i dynamicznie alokował pamięć dla niej. Napisz funkcję która będzie uzupełniała tablicę ​iloczynami wierszy i kolumn ​i osobną funkcję do wyświetlania tablicy. Czy można do tego wykorzystać funkcje napisane na poprzednich laboratoriach nie modyfikując ich? Pamiętaj o **poprawnym** zwolnieniu pamięci! {{.:​pointers2pointers.png|Tablica wskaźników}}. Zadanie zostało podzielone na kroki: (step1,​step2,​...). Ukończenie pierwszego i drugiego kroku jest wymagane do zaliczenia ćwiczenia.+  - [1 plus] W sekcji [[#​wskazniki_i_alokacja_pamieci|Wskaźniki i alokacja pamięci]] zostało powiedziane,​ że **nie można** utworzyć tablicy wielowymiarowej prostym poleceniem //int * *tab = new int[10][10]//​. Przeanalizuj rysunek poniżej i zastanów się dlaczego tak jest. Następnie napisz program który będzie pobierał od użytkownika wymiary tablicy i dynamicznie alokował pamięć dla niej. Napisz funkcję która będzie uzupełniała tablicę ​kolejnymi liczbami całkowitymi (tak jak na rysunku) ​i osobną funkcję do wyświetlania tablicy. Czy można do tego wykorzystać funkcje napisane na poprzednich laboratoriach nie modyfikując ich? Pamiętaj o **poprawnym** zwolnieniu pamięci! {{.:​pointers2pointers.png|Tablica wskaźników}}. Zadanie zostało podzielone na kroki: (step1,​step2,​...). Ukończenie pierwszego i drugiego kroku jest wymagane do zaliczenia ćwiczenia.
     * Moduł: **array2d**     * Moduł: **array2d**
-    * Pliki z implementacją:​ **Array2d.h/cpp**+    * Pliki z implementacją:​ **Array2D.h/cpp**
     * Sygnatura metody: <code cpp>int **Array2D(int n_rows, int n_columns);     * Sygnatura metody: <code cpp>int **Array2D(int n_rows, int n_columns);
 void DeleteArray2D(int **array, int n_rows, int n_columns);</​code>​ void DeleteArray2D(int **array, int n_rows, int n_columns);</​code>​
Linia 220: Linia 354:
   - [2 plusy] Wykorzystując strukturę danych (struct) znaną jeszcze z języka C, należy zaimplementować listę jednokierunkową zdolną przechowywać liczby całkowite w swoich węzłach. **UWAGA**: jest to ćwiczenie tylko techniczne, w standardowej bibliotece istnieje [[http://​en.cppreference.com/​w/​cpp/​container/​forward_list|forward_list]] zdolna przechowywać dowolny typ.   - [2 plusy] Wykorzystując strukturę danych (struct) znaną jeszcze z języka C, należy zaimplementować listę jednokierunkową zdolną przechowywać liczby całkowite w swoich węzłach. **UWAGA**: jest to ćwiczenie tylko techniczne, w standardowej bibliotece istnieje [[http://​en.cppreference.com/​w/​cpp/​container/​forward_list|forward_list]] zdolna przechowywać dowolny typ.
     * Moduł: **simpleforwardlist**     * Moduł: **simpleforwardlist**
-    * Pliki z implementacją:​ **ForwardList.h/cpp**+    * Pliki z implementacją:​ **SimpleForwardList.h/cpp**
     * Sygnatury metod: <code cpp>​ForwardList *CreateNode(int value);     * Sygnatury metod: <code cpp>​ForwardList *CreateNode(int value);
 void DestroyList(ForwardList *list);</​code>​ void DestroyList(ForwardList *list);</​code>​
Linia 247: Linia 381:
     * Pliki nagłówkowe:​ <code cpp>#​include <​string>​     * Pliki nagłówkowe:​ <code cpp>#​include <​string>​
 #include <​vector></​code>​ #include <​vector></​code>​
 +    * Wskazówki: <code cpp>#​include <​algorithm>​
 +using std::find;
 +using std::​vector;​
 +using std::​string;​
 +
 +vector<​string>​ dictionary {"​the","​of"​};​
 +
 +//THERE ARE BETTER WAYS TO LOOK FOR A WORD BUT IT WORKS
 +if (find(dictionary.begin(),​dictionary.end(),"​of"​) != dictionary.end()) {
 +   //​FOUND!
 +}
 +
 +</​code>​
pl/dydaktyka/jimp2/2017/labs/pamiec-i-pliki.1488551422.txt.gz · ostatnio zmienione: 2019/06/27 15:52 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0