Analiza konstrukcji zawierających wskaźniki. Piotr Błaszyński

Podobne dokumenty
Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Wskaźniki. Programowanie Proceduralne 1

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Wstęp do programowania

Języki i metodyka programowania. Wskaźniki i tablice.

DYNAMICZNE PRZYDZIELANIE PAMIECI

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Wstęp do programowania. Procedury i funkcje. Piotr Chrząstowski-Wachtel

Algorytmy i złożoności. Wykład 3. Listy jednokierunkowe

ZASADY PROGRAMOWANIA KOMPUTERÓW

Algorytmy i język C++

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

> C++ wskaźniki. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki 26 kwietnia 2017

6 Przygotował: mgr inż. Maciej Lasota

Język C zajęcia nr 11. Funkcje

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 8. Karol Tarnowski A-1 p.

Programowanie obiektowe i C++ dla matematyków

Podstawy programowania w języku C++

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

Podstawy Programowania 2 Grafy i ich reprezentacje. Plan. Wstęp. Teoria grafów Graf skierowany. Notatki. Notatki. Notatki. Notatki.

. Podstawy Programowania 2. Grafy i ich reprezentacje. Arkadiusz Chrobot. 9 czerwca 2016

Ogólne wiadomości o grafach

Podstawy programowania. Wykład 6 Złożone typy danych: struktury, unie. Krzysztof Banaś Podstawy programowania 1

Bardzo szybkie podsumowanie: wykład 3

Poprawność semantyczna

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

ALGORYTMY I STRUKTURY DANYCH

Tablice, funkcje, wskaźniki - wprowadzenie

Dynamiczny przydział pamięci w języku C. Dynamiczne struktury danych. dr inż. Jarosław Forenc. Metoda 1 (wektor N M-elementowy)

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

Wykład 4: Klasy i Metody

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 8. Karol Tarnowski A-1 p.

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Podstawy programowania skrót z wykładów:

Podstawy programowania 2. Temat: Funkcje i procedury rekurencyjne. Przygotował: mgr inż. Tomasz Michno

Rozdział 4 KLASY, OBIEKTY, METODY

Zmienne i struktury dynamiczne

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wskazówki dotyczące zmiennych, tablic i procedur 1

Grafem nazywamy strukturę G = (V, E): V zbiór węzłów lub wierzchołków, Grafy dzielimy na grafy skierowane i nieskierowane:

Podstawy programowania komputerów

Materiał uzupełniający do ćwiczen z przedmiotu: Programowanie w C ++ - ćwiczenia na wskaźnikach

PROE wykład 2 operacje na wskaźnikach. dr inż. Jacek Naruniec

Podstawy Programowania 2 Dwukierunkowa lista liniowa. Plan. Wstęp. Implementacja. Notatki. Notatki. Notatki. Notatki.

Lab 9 Podstawy Programowania

Wskaźniki w C. Anna Gogolińska

Podstawy programowania w języku C++

Podstawy programowania w języku C++

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Wstęp do sieci neuronowych, wykład 11 Łańcuchy Markova

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy WSKAŹNIKI KLASOWE

. Podstawy Programowania 2. Dwukierunkowa lista liniowa. Arkadiusz Chrobot. 7 kwietnia 2019

KURS C/C++ WYKŁAD 6. Wskaźniki

Funkcja, argumenty funkcji

Programowanie i struktury danych

typ y y p y z łoż o on o e n - tab a lice c e w iel e owym m ar a o r we, e stru r kt k ury

Zasady programowania Dokumentacja

Teoretyczne podstawy informatyki

Zapis algorytmów: schematy blokowe i pseudokod 1

Pole wielokąta. Wejście. Wyjście. Przykład

Algorytm. a programowanie -

Argumenty wywołania programu, operacje na plikach

Deklaracja struktury w C++

Wieczorowe Studia Licencjackie Wrocław, Wykład nr 6 (w oparciu o notatki K. Lorysia, z modyfikacjami) Sito Eratostenesa

Tablice, funkcje - wprowadzenie

Część 4 życie programu

E S - uniwersum struktury stosu

1. Algorytmy przeszukiwania. Przeszukiwanie wszerz i w głąb.

część 8 wskaźniki - podstawy Jarosław Gramacki Instytut Informatyki i Elektroniki Podstawowe pojęcia

Wstęp do sieci neuronowych, wykład 12 Łańcuchy Markowa

Język C++ zajęcia nr 2

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

WYKŁAD 10. Zmienne o złożonej budowie Statyczne i dynamiczne struktury danych: lista, kolejka, stos, drzewo. Programy: c5_1.c, c5_2, c5_3, c5_4, c5_5

Wstęp do programowania

Zaawansowane programowanie w języku C++ Zarządzanie pamięcią w C++

Drzewa poszukiwań binarnych

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Programowanie Niskopoziomowe

E: Rekonstrukcja ewolucji. Algorytmy filogenetyczne

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 6. Karol Tarnowski A-1 p.

Wskaźniki. Informatyka

Algorytm Dijkstry znajdowania najkrótszej ścieżki w grafie

Warto też w tym miejscu powiedzieć, że w C zero jest rozpoznawane jako fałsz, a wszystkie pozostałe wartości jako prawda.

Podstawy programowania w języku C++

Lab 10. Funkcje w argumentach funkcji metoda Newtona. Synonimy nazw typów danych. Struktury. Tablice struktur.

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Informatyka I: Instrukcja 4.2

Struktury. Przykład W8_1

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy KONSTRUKTORY

Transkrypt:

Analiza konstrukcji zawierających wskaźniki Piotr Błaszyński

Wskaźniki podejście naiwne: while(ptr!=null){ a[i] = *ptr; i++; ptr++; } po zmianie: N=length(ptr); alias_ptr = ptr; for(j=0 ; j<n ; j++){ a[i] = alias_ptr[j]; i++; }

Wskaźniki czy kod o złożonej strukturze operacji na wskaźnikach można zrównoleglić: struktury danych o swobodnych powiązaniach (heap modelling) struktury danych odworowujące kolekcje, przypominające tablice (aggregate modelling) aliasy do innych miejsc w pamięci (alias representation). restrict (nowe słowo kluczowe C99).

Przykład x := 5 ptr := @x *ptr := 9 y := x progra m S 1 S 2 S 3 S 4 zależności Problem: Nie można uzyskać informacji o zależnościach patrząc jedynie na nazwy zmiennych, bo: po wykonaniu wyrażenia S2, zmienne x i ptr wskazują na to samo miejsce w pamięci, czyli ptr wskazuje (points-to) na x po wykonaniu S2. W językach podobnych do C i posiadających wskaźniki, potrzebna jest wiedza o powyższych relacjach żeby prawidłowo określic zależności

Propozycja rozwiązania Dla uproszczenia tylko 2 typy:int i int* Brak sterty, wszystkie wskaźniki wskazują tylko na zmienne znajdujące się na stosie Brak wywołań funkcji Jedyne wyrażenia wpływające na zmienne wskaźnikowe: wyłuskanie adresu: x = &y kopia: x = y załadowanie wartości: x = *y przechowanie wartości: *x = y Obliczenia też dają w wyniku int

Graf zależności Graf skierowany (z grotami strzałek): węzły to zmienne krawędzie (a,b): zmienna a wskazuje na zmienną b x pt r y specjalny węzeł na NULL Graf ten wygląda różnie w różnych miejscach programu

Graf zależności Węzeł może mieć więcej niż 1 krawędź wyjściową jeżeli graf zależności ma krawędzie (a,b) i (a,c), to znaczy, że zmienna a może wskazywać zarówno na zmienną b jak i c w zależności od tego w jaki sposób program dotarł do tego punktu jedno z tych wskazań może być prawdziwe analiza z uwzględnieniem ściezki wykonania (path-sensitive) jest trudna do wykonania (statycznie) if (p) x = &y else x := &z.. x = &y Na co wskazuje teraz x? p x = &z

Graf zależności - porządkowanie Porządkowanie podzbioru zmiennych: Najmniejszym elementem jest graf bez krawędzi, G1 <= G2 jeżeli graf G2 ma wszystkie krawędzie grafu G1 i ewentualnie jakies dodatkowe G1 U G2 najmniejszy graf który zawiera wszystkie krawedzie G1 i G2

Analiza Trzy sposoby (algorytmy): Analiza zależna od przepływu Tak naprawdę analiza przepływu danych Wyznacza się w niej dokładne wskazania w poszczególnych momentach programu (wiele grafów)

Analiza Analiza niezależna od przepływu Wyznacza się jeden graf dla całego programu Algorytm Andersena Jest naturalnym uproszczeniem algorytmów zależnych od przepływu Algorytm Steensgarda Węzły w grafie są grupowane (z kilku zmiennych, pomiędzy którymi zachodzi równoważność) jeżeli x może wskazywać zarówno na y i z, to wtedy y i z są traktowane jako równoważne (umieszcza się je w klasie równoważności) Graf zależności ma krawędzie od "potomków" do "rodziców" Mniej dokładny (od alg. Andersena), ale szybszy

Wskaźniki ptr x z y w ptr x z y w x := &z ptr := &x Andersen y := &w ptr := &y pt r x, y z,w Steensgard

Struktury Przykładowa struktura struct cell {int value; struct cell *left, *right;} struct cell x,y; Podejście uzwględniające pola x i y są węzłami każdy węzeł ma 3 wewnetrzne pola: value, left, right Taka reprezentacja uzwględnia wskazania do wnętrza struktur Jeżeli to nie jest konieczne, można po prostu przyjąć, że pojedynczy węzeł przesdtawia jedną strukturę i tylko opisywać krawędzie przy pomocy nazw pól

Przykład int main(void) { struct cell {int value; struct cell *next; }; struct cell x,y,z,*p; int sum; x.value = 5; x.next = &y; y.value = 6; y.next = &z; z.value = 7; z.next = NULL; p = &x; sum = 0; while (p!= NULL) { sum = sum + (*p).value; p = (*p).next; } return sum; } x valu e x valu e nex t p nex t p y valu e y z valu e nex t valu e z nex t valu e nex t NULL nex t NULL

Bez uwzględniania przepływu x valu e nex t y valu e nex t z p valu e nex t NULL - Czemu p wskazuje również na NULL?

Funkcje x1 = &a y1 = &b swap(x1, y1) x2 = &a y2 = &b swap(x2, y2) swap (p1, p2) { t1 = *p1; t2 = *p2; *p1 = t2; *p2 = t1; }

Funkcje Uwzględnianie kontekstu Traktujemy każde wywołanie funkcji oddzielnie tak jak to faktycznie dzieje się w programie problem: Co z funkcjami rekurencyjnymi? niestety trzeba szacować Bez uwzględniania kontekstu Łączymy informacje z różnych miejsc wywołańdanej funkcji na skutek czego tak naprawdę, problem sprowadzony zostaje do rozwiązania zalęzności wewnątrz danej funkcji Podejście uwzględniające kontekst jest oczywiście bardziej precyzyjne ale bardziej kosztowne do wyznaczenia

Bez uwzględniania kontekstu x1 = &a y1 = &b swap(x1, y1) x2 = &a y2 = &b swap(x2, y2) swap (p1, p2) { t1 = *p1; t2 = *p2; *p1 = t2; *p2 = t1; }

Uwzględnianie kontekstu x1 = &a y1 = &b swap(x1, y1) x2 = &a y2 = &b swap(x2, y2) swap (p1, p2) { t1 = *p1; t2 = *p2; *p1 = t2; *p2 = t1; } swap (p1, p2) { t1 = *p1; t2 = *p2; *p1 = t2; *p2 = t1; }

Funkcje Założenie: brak parametrów funkcji Oznacza to, że znamy wszystkie wywołania, bo inaczej: Konieczne jest wykonanie przypisania parametrów aktualny i parametrów formalnych w każdym miejscu wywołania Używamy tych samych zmiennych dla wszystkich nazw parametrów formalnych w poszczególnych miejcach wywołania Każde wywołanie powoduje wygenerowanie nowego zbioru powiązań do parametrów formalnych

Przykład x1 = &a y1 = &b p1 = x1 p2 = y1 x2 = &a y2 = &b p1 = x2 p2 = y2 t1 = *p1; t2 = *p2; *p1 = t2; *p2 = t1;

Alokacja pamięci (sterta) Najprostsze rozwiązanie: stosowanie jednego węzła w grafie do reprezentowania wszystkich komórek pamięci sterty Bardziej złożone rozwiązanie: dla każdego malloc w programie uzyć innego węzła Jeszcze bardziej wyszukane rozwiązanie: analiza kształtu cel: synteza potencjalnie nieskończonych struktur, ale zachowane jest wystarczająco dużo informacji, dzięki czemu możemy rozróżnić wskaźniki ze stosu do sterty, o ile to w ogóle możliwe

Podsumowanie Mniej dokładne metody Oparte na jednoznaczności Metody dokładniejsze Oparta na podzbiorach bez uwzględniania przepływu bez uwzględniania kontekstu uwzględnianie przepływu uzględnianie kontekstu Brak jednoznacznej odpowiedzi, której metody użyć.