IN 147 Program og maskinvare

Like dokumenter
Pekere og vektorer. Dagens tema. I C gjelder en litt uventet konvensjon:

Dagens tema. Det siste om C Pekere og vektorer. Pekere til pekere. Vanlige pekerfeil. struct-er og typedef. Lister. Feilsøking

IN 147 Program og maskinvare

IN 147 Program og maskinvare. Vanlige feil ved bruk av pekere Feilsøking Debuggere

Dagens tema INF1070. Info om C. Cs preprosessor. Feilsøking. Dag Langmyhr,Ifi,UiO: Forelesning 31. januar 2005 Ark 1 av 29

Informasjon om C. Dagens tema INF1070 INF1070 INF1070 INF1070. Den viktigste kilden til informasjon om C (utenom en god. C-funksjonene.

Dagens tema INF1070. Signaturer. Typekonvertering. Pekere og vektorer. struct-er. Definisjon av nye typenavn. Lister

Dagens tema. Adresser som parametre Dynamisk allokering Signaturer Definisjon av nye typenavn Typekonvertering Pekere og vektorer

IN 147 Program og maskinvare

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Programmeringsspråket C Del 3

Signaturer. Dagens tema. En vanlig feil int-funksjon. Dette kan noen ganger gi rare feilmeldinger: INF1070 INF1070 INF1070 INF1070

Dagens tema INF2270. Signaturer. Typekonvertering. Pekere og vektorer. struct er. Definisjon av nye typenavn. Lister. Info om C

Programmeringsspråket C Del 3. Michael Welzl

IN 147 Program og maskinvare

Dagens tema C, adresser og pekere

Ark 3 av 26. printf("i adresse %08x ligger b med verdien %d.\n", &b, b); printf("i adresse %08x ligger a med verdien %d.

Dagens program. Operativsystemer Prosesser og systemkall i UNIX Hente prosessens nummer Starte prosesser Vente på prosesser Utføre programmer

Dagens tema. Dynamisk allokering Signaturer Definisjon av typer og nye typenavn Typekonvertering Pekere, vektorer og lister Dokumentasjon

Signaturer. Dagens tema

IN 147 Program og maskinvare

Dagens tema INF1070. Vektorer (array er) Tekster (string er) Adresser og pekere. Dynamisk allokering

Vektorer. Dagens tema. Deklarasjon. Bruk

Del 4 Noen spesielle C-elementer

Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

Programmeringsspråket C Del 2

Dagens tema INF1070. Vektorer (array-er) Tekster (string-er) Adresser og pekere. Dynamisk allokering

IN 147 Program og maskinvare

Debuggere En «debugger» er et meget nyttig feilsøkingsverktøy. Det kan analysere en program dump, Dagens tema INF1070 INF1070 INF1070 INF1070

Del 1 En oversikt over C-programmering

Oversikt. Introduksjon Kildekode Kompilering Hello world Hello world med argumenter. 1 C programmering. 2 Funksjoner. 3 Datatyper. 4 Pekere og arrays

Dagens tema INF2270. Cs preprosessor. Separat kompilering av C funksjoner. C og minnet. Dag Langmyhr,Ifi,UiO: Forelesning 5. februar 2007 Ark 1 av 15

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Programmeringsspråket C

Nybegynnerkurs i C. Øyvind Grønnesby. 14. oktober Introduksjon Typer Operatorer Kontrollstrukturer Pekere Makroer Lenker

Programmeringsspråket C Del 2. Michael Welzl

Dagens tema. Cs preprosessor Separat kompilering av C-funksjoner C og minnet Oversikt over operatorene

Kapittel 1 En oversikt over C-språket

Programmeringsspråket C

OPPGAVE 1 OBLIGATORISKE OPPGAVER (OBLIG 1) (1) Uten å selv implementere og kjøre koden under, hva skriver koden ut til konsollen?

Cs preprosessor. Dagens tema. Betinget kompilering

Programmeringsspråket C

Programmering i C++ Løsningsforslag Eksamen høsten 2005

Programmeringsspråket C Del 3. Hans Petter Taugbøl Kragset

Debugging. Tore Berg Hansen, TISIP

Dagens tema. C-programmering. Nøkkelen til å forstå C-programmering ligger i å forstå hvordan minnet brukes.

Repetisjon: Statiske språk uten rekursive metoder (C1 og C2) Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Dagens tema Kjøresystemer (Ghezzi&Jazayeri 2.6, 2.7)

Oppgavene 1, 2, 4, 5, 6, 9, 12 og 13 passer best til å løses ved en datamaskin.

Dagens tema: Kjøresystemer II

Dagens tema. Cs preprosessor Separat kompilering av C-funksjoner C og minnet Oversikt over operatorene

Dagens tema: Datastrukturer

EKSAMEN. Operativsystemer. 1. Læreboken "A Practical Guide to Red Hat Linux" av Mark Sobell 2. Maks. tre A-4 ark med selvskrevne notater.

Dagens tema: Enda mer MIPS maskinkode

Programmeringsspråket C Del 2. Hans Petter Taugbøl Kragset

Rutiner [REB&DRO H 3.7]

Dagens tema. Kort repetisjon om rutiner. Programmering i C Variable og adresser. Vektorer. Tekster. Preprosessoren. Separat kompilering

IN 147 Program og maskinvare. Dagens tema

Oving 2. Oppgave 1. #include <stdio.h> int main(int argc, char **argv) { char *navn = argv[1]; printf ("Navnet ditt er %s\n", navn); } Oppgave 2

2 Om statiske variable/konstanter og statiske metoder.

Repetisjon fra sist - 1: Plan for dagen. Repetisjon fra sist 2: Hva jeg glemte sist: Nyttige Kommandoer

INF1000 : Forelesning 4

Oppsummering av IN147 siste del Operativsystemer Parallellisering Veien videre

i=0 i=1 Repetisjon: nesting av løkker INF1000 : Forelesning 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker j=0 j=1 j=2 j=3 j=4

Dagens tema. Mer om C Enkle datatyper Sammensatte datatyper: Vektorer og matriser Tekster Mengder Strukturer Unioner Ringbuffere

Hvordan en prosessor arbeider, del 1

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Del 3. Pekere RR 2016

Ark 1 av 18. programmeringsspråkenes. Velkommen til IN 211. verden. IN 211 Programmeringsspråk

IN 147 Program og maskinvare

INF1000 (Uke 5) Mer om løkker, arrayer og metoder

Dagens tema. Rutiner i LC-2 Og her er tilsvarende kode for LC-2: Funksjoner i C Her er det samme programmet i C: Kort repetisjon om rutiner

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Dagens tema. 2. Feilsøking. 1. Minnet. Fast minne. gdb ddd Valgrind Egne testutskrifter. Noen nyttige instruksjoner. Bit-fikling

Forelesning inf Java 4

INF225 høsten 2003 Prosjekt del 4: kodegenerering

Dagens tema. Hva er kompilering? Anta at vi lager dette lille programmet doble.rusc (kalt kildekoden): Hva er kompilering?

Dagens tema. Oppsummering om assemblerspråk. Programmering i C. Bakgrunn. Et minimalt eksempel med forklaring. Datatyper i C.

Runtimesystemer - II. Funksjoner som parametere. Virtuelle metoder

Dagens tema. Nyttige programmer Programmet make. Hvis én fil endres, hvilke filer må da kompileres på nytt?

IN 147 Program og maskinvare

Dagens tema 1: Minnet

HØYSKOLEN I OSLO, AVDELING FOR INGENIØRUTDANNING

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Dagens tema. Perl: Mer om regulære uttrykk Filer Lister og tabeller Kompilering og interpretering (kapittel ) IN 211 Programmeringsspråk

Del 2 Tabeller, arrays, strenger

Dagens tema. Nyttige programmer Programmet make. Flyt-tall Representasjon av flyt-tall. Standarden IEEE 754. Systemkall i Unix

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Dagens tema: 12 gode råd for en kompilatorskriver

Den siste dagen. Pensumoversikt Hovedtanker i kurset Selvmodifiserende kode Overflyt Veien videre... Eksamen

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Det viktigste i en moderne datamaskin er hovedkortet («motherboard»):

Diverse eksamensgaver

Transkript:

Dagens tema Deklarasjon av nye typer Typekonvertering mellom pekere Regning med pekere Pekere til funksjoner Pekere til pekere til... Vanlige feil ved bruk av pekere Feilsøking Debuggere lint Kompilatormeldinger Egne testutskrifter Ark 1 av 28 Forelesning 1.3.2000

Deklarasjon av nye typer I C kan vi definere nye typer: typedef unsigned char uc; uc c1, ctab[10]; Typedefinisjoner brukes til å unngå lange navn: uc kontra unsigned char punkt kontra struct punkt definisjoner som kan variere fra ett system til et annet; for eksempel i stdlib.h på en SGI: typedef unsigned int size_t; Typen size t brukes som type for en størrelse, for eksempel det sizeof gir. Forelesning 1.3.2000 Ark 2 av 28

Typekonvertering mellom pekere Siden pekere i prinsippet kan være av ulikt antall bit, skal man egentlig angi konvertering mellom dem. (Dette hjelper også kompilatoren å finne feil.) Pekertypen void* er garantert stor nok til alle pekere, og kan derfor betraktes som en «peker til alt mulig». Funksjonen malloc er derfor definert som void *malloc (size_t size) Korrekt bruk av malloc er derfor xxx *p; : p=(xxx*)malloc(sizeof(xxx)); Forelesning 1.3.2000 Ark 3 av 28

Regning med pekere I C gjelder alltid at a[i] *(a+i) Dette er greit om a er en char-vektor, men hva om den er en long? Egne regneregler for pekere I C gjelder egne regneregler for pekere: p+i betyr «Øk p med i multiplisert med størrelsen av det p peker på.» #include <stdio.h> typedef unsigned long ul; int main(void) { char *cp = (char*)0x123400; long *lp = (long*)0x123400; cp++; lp++; printf("cp = 0x%lx\nlp = 0x%lx\n", (ul)cp, (ul)lp); return 0; } gir følgende når det kjøres: cp = 0x123401 lp = 0x123404 Forelesning 1.3.2000 Ark 4 av 28

Pekere til funksjoner Det er nyttig å kunne behandle funksjoner som om de var variable, og noen høynivåspråk tilbyr dette. C tilbyr noe som er nesten like godt: pekere til funksjoner. #include <stdio.h> int sum(int (*f)(int x), int n) { /* Beregn summen av f(x) for x=1,...,n. */ int res = 0, ix; for (ix = 1; ix <= n; ++ix) res += f(ix); } return res; Her er parameteren f en peker til en funksjon: Denne funksjonen returnerer en int. Denne funksjonen har én parameter: n som er en int. Forelesning 1.3.2000 Ark 5 av 28

Bruk av funksjonspekere Bruk av et funksjonsnavn uten parenteser bak, gir en peker til funksjonen. (Dette implementeres som adressen til første instruksjon i funksjonen.) int odd(int x) /* Er x et oddetall? */ { return x%2; } int sqr(int v) /* Finn kvadratet av v. */ { return v*v; } int main(void) { printf("sum av odd(n): %5d\n", sum(odd,10)); printf("sum av sqr(n): %5d\n", sum(sqr,10)); return 0; } Kjøring av dette lille programmet gir følgende resultat: Sum av odd(n): 5 Sum av sqr(n): 385 Forelesning 1.3.2000 Ark 6 av 28

Pekere til pekere til... Noen ganger trenger man en peker til en pekervariabel (for eksempel fordi den skal overføres som parameter og endres). Siden vanlige pekere deklareres som xxx *p; må en «peker til en peker» angis som xxx **pp = &p; Dette kan utvides med så mange stjerner man ønsker. Eksempel Omgivelsesvariable i UNIX inneholder opplysninger om en bruker og hans eller hennes preferanser: LOGNAME=dag PAGER=less HOSTTYPE=sgi PRINTER=prent HOME=/home/ansatte/03/dag SHELL=/local/gnu/bin/bash Forelesning 1.3.2000 Ark 7 av 28

Omgivelsen overføres nesten alltid fra program til program ved en tredje parameter til main: int main(int argc, char *argv[], char **envir) Parameteren envir peker på en vektor av pekere som hver peker på en omgivelsesvariabel og den definisjon. LOGNAME=dag envir 0 PAGER=less HOSTTYPE=sgi PRINTER=prent HOME=/home/ansatte/03/dag SHELL=/local/gnu/bin/bash Forelesning 1.3.2000 Ark 8 av 28

Vanlige pekerfeil Det er noen feil som går igjen: Glemme initiering av pekeren! long *p; printf("verdien er %ld.\n", *p); Glemme frigjøring av objekt! long *p; p = (long*)malloc(sizeof(long)); p = NULL; Det allokerte objektet vil nå være utilgjengelig, men vil «flyte rundt» og oppta plass så lenge programmet kjører. Dette kalles en hukommelseslekkasje. Forelesning 1.3.2000 Ark 9 av 28

La en global peker peke på lokal variabel! long *p; void f(void) { long x; } p = &x; f(); p peker nå på en variabel som ikke finnes mer. Stedet på stakken der x lå, kan være tatt i bruk av andre funksjoner. Peke på resirkulert objekt! long *p, *q; p = q = (long*)malloc(sizeof(long)); free(p); p = NULL; q peker nå på et objekt som er frigjort og som kanskje er tatt i bruk gjennom nye kall på malloc. Forelesning 1.3.2000 Ark 10 av 28

Feilsøking Hva gjør vi når alt bare går galt? #include <stdio.h> #include <stdlib.h> int *vec[10]; int main(void) { int i; for (i = 0; i<10; ++i) { vec[1] = (int*)malloc(sizeof(int)); *vec[i] = i; } for (i = 9; i>=0; --i) { printf("vec[%d] peker på %d.\n", i, *vec[i]); } return 0; } Forelesning 1.3.2000 Ark 11 av 28

Forsøk på å kjøre dette programmet gir bare Segmentation Fault Dette forteller om en ulovlig peker/adresse, men hvor? I hvilken programkodelinje skjedde feilen? Hva var situasjonen da? Nærmere bestemt vil vi gjerne vite Hva inneholder de ulike variablene? Hva er kallkjeden (dvs hvilke funksjoner er kalt, og hvorfra)? Forelesning 1.3.2000 Ark 12 av 28

Debuggere En «debugger» er et meget nyttig feilsøkingsverktøy. Det kan analysere en program-dump, vise innholdet av variable, vise hvilke funksjoner som er kalt, kjøre programmet én og én linje, og kjøre til angitt stoppunkter. Debuggeren gdb er laget for å brukes sammen med både cc og gcc. Denharet vindusgrensesnitt som heter ddd. For å bruke gdb/ddd må vi gjøre to ting: kompilere våre programmer med opsjonen -g, og angi at vi ønsker programdumper: ulimit -c unlimited hvis vi bruker bash. (Da må vi huske å fjerne programdumpfilene selv; de er store!) Forelesning 1.3.2000 Ark 13 av 28

Programdumper Når et program dør på grunn av en feil («aborterer»), prøver det ofte å skrive innholdet av hele prosessen på en fil slik at det kan analyseres siden. 1. Programmet kompileres med debuggingsinformasjon: maskin navn> cc -g test-gdb.c -o test-gdb 2. Programmet kjøres: maskin navn> test-gdb Segmentation Fault (core dumped) maskin navn> ls -l core -rw-r--r-- 1 dag dag 136284 Feb 28 13:28 core Dette kalles ofte en «core-dump» siden datamaskinene for 20 40 år siden hadde hurtiglager bygget opp av ringer med kjerne av feritt. I UNIX heter denne filen derfor core. Forelesning 1.3.2000 Ark 14 av 28

maskin navn> /local/hacks/sgi/bin/ddd test-gdb & Forelesning 1.3.2000 Ark 15 av 28

I File-menyen finner vi «Open Core Dump». Forelesning 1.3.2000 Ark 16 av 28

Nå vet vi at feilen oppsto på linje 12 i forbindelse med *vec[i] = i. Kanskje det er noe galt med indeksen i? I Data-menyen finner vi «Display Local Variables» Forelesning 1.3.2000 Ark 17 av 28

Variabelen i er 0, så den er OK. Hva da med vec? Vi kan klikke på en forekomst av vec og så «New Display». Forelesning 1.3.2000 Ark 18 av 28

Her ser vi at vec[0] er 0 mens vec[1] peker på noe; det burde vært omvendt! (vec[1] vec[9] skal ennå ikke ha fått noen verdi (siden i er 0).) Altså oppsto feilen under initieringen av vec der det står for (i = 0; i<10; ++i) { vec[1] = (int*)malloc(sizeof(int)); *vec[i] = i; } Vi kan da avslutte ddd med «Exit» i File-menyen. Forelesning 1.3.2000 Ark 19 av 28

Et eksempel til Følgende program skal skrive ut sine parametre og alle omgivelsesvariablene: #include <stdio.h> int main(int argc, char *argv[], char **envir) { char **p = envir, *e; int i; for (i = 0; i < argc; ++i) { printf("parameter %d: %s \n", i, argv[i]); } while (! (*p = NULL)) { e=*p; printf("%s\n", e); ++p; } return 0; } Kompilering går fint: maskin navn> cc -g printenv-feil.c -o printenv-feil men kjøringen går dårlig: maskin navn> printenv-feil a b Parameter 0: printenv-feil Parameter 1: a Parameter 2: b (null) (null). Control + \ Quit (core dumped) Forelesning 1.3.2000 Ark 20 av 28

Hva sier gdb/ddd? maskin navn> /local/hacks/sgi/bin/ddd printenv-feil & Forelesning 1.3.2000 Ark 21 av 28

Her ser vi imidlertid at feilen er oppstått i write, men den kaller vi da ikke i vårt program? Vi ber om «Backtrace» i Status-menyen. Forelesning 1.3.2000 Ark 22 av 28

Vi ser at feilen oppsto i linje 14 i main i kallet på printf. Vi klikker på «Up» fire ganger, og velger så «Display Local Variables» i Data-menyen. Vi ser at p ser OK ut, men e burde vel ikke være 0? La oss kjøre programmet på nytt, men legge inn et stoppunkt øverst i while-løkken. Pek og klikk på linjen, og så på «Break at ()». Så kan vi klikke på «Run» igjen. Forelesning 1.3.2000 Ark 23 av 28

Forelesning 1.3.2000 Ark 24 av 28

Etter at programmet er stoppet før det skal utføre while-løkken for første gang, lar vi det utføre de to første linjene ved å klikke på «Step». Forelesning 1.3.2000 Ark 25 av 28

Her ser vi at e er 0, og det må være galt! Dette skjedde i den gale testen while (! (*p = NULL)) { som burde vært skrevet while (*p!= NULL) { eller while (*p) { Konklusjon Noen timer brukt på å lære seg gdb og ddd får man mangedobbelt igjen senere i kurset! Forelesning 1.3.2000 Ark 26 av 28

Andre feilsøkingverktøy Programmet lint Dette programmet sjekker C-programmer og rapporterer mulig feil og foreslår hvorledes koden kan forbedres. maskin navn> lint prog.c (37) warning: variable may be used before set: q (37) warning: evaluation order undefined: q (37) warning: variable may be used before set: p (37) warning: evaluation order undefined: q (37) warning: evaluation order undefined: p (38) warning: argument mismatch: 1 arg passed, 0 expected (39) warning: variable may be used before set: x (88) warning: function returns value that is always ignored: printf variable unused in function (11) end in define (6) begin in define Kompilatormeldinger Noen ganger kan kompilatoren gi fornuftige advarsler om potensielle farer hvis man ber om det: maskin navn> cc -fullwarn printenv-feil.c Egne meldinger Det aller beste er å regne med at man gjør feil og legge inn egne utskrifter som kan slås av og på ved behov. Forelesning 1.3.2000 Ark 27 av 28

Programmet purify Dette kommersielle programmet legger inn alle mulig tester som blir utført under kjøringen: maskin navn> purify cc test-gdb.c -o test-gdb Purify 4.1 IRIX6, Copyright (C) 1992-1997 Rational Software Corp.... Processing "/usr/lib/libc.so.1"... Processing "test-gdb" Når feil oppstår, kommer et meldingsvindu: Forelesning 1.3.2000 Ark 28 av 28