Forskjell mellom versjoner av «Vanlige feil i oblig og hjemmeeksamen»

Fra mn/ifi/INF1060
Hopp til: navigasjon, søk
(Ny side: Vanlige feil i oblig og hjemmeeksamen Her er en kjapp oversikt over feil mange gjør i Oblig 1 og hjemmeeksamenene. == Innlevering av hjemmeeksamen inneholder navn på kandidaten == Innl…)
 
 
(2 mellomliggende revisjoner av samme bruker vises ikke)
Linje 1: Linje 1:
Vanlige feil i oblig og hjemmeeksamen
 
 
 
Her er en kjapp oversikt over feil mange gjør i Oblig 1 og hjemmeeksamenene.
 
Her er en kjapp oversikt over feil mange gjør i Oblig 1 og hjemmeeksamenene.
  
Linje 6: Linje 4:
  
 
Innleveringen skal være anonym, så skriv ikke «Hilsen ditt_navn» i readme, eller «author ditt_navn» i kildekoden. Slikt vil gi trekk!
 
Innleveringen skal være anonym, så skriv ikke «Hilsen ditt_navn» i readme, eller «author ditt_navn» i kildekoden. Slikt vil gi trekk!
Kopiere en string
+
 
 +
== Kopiere en string ==
  
 
  char *string1 = "Tullball";
 
  char *string1 = "Tullball";
Linje 15: Linje 14:
 
Hvis du kjører koden ovenfor vil du se at de to variablene inneholder samme minneadresse. Det vil si at begge peker på samme sted i minnet, og følgelig samme data. Endringer i den ene vil føre til endringer i den andre.
 
Hvis du kjører koden ovenfor vil du se at de to variablene inneholder samme minneadresse. Det vil si at begge peker på samme sted i minnet, og følgelig samme data. Endringer i den ene vil føre til endringer i den andre.
  
For å lage en kopie av en string må man setter av et nytt minneområde, og kopierer stringen over i denne.
+
For å lage en kopi av en string må man sette av et nytt minneområde, og kopiere stringen over i denne.
  
 
== Allokere plass til en string ==
 
== Allokere plass til en string ==
Linje 23: Linje 22:
 
  char *string = malloc(10);
 
  char *string = malloc(10);
  
Det mange tror er at denne stringen nå har plass til 10 tegn. Det har den på et vis, men det siste tegnet må alltid være 0. Dette kalles null-byten, og er det som terminerer stringen slik at man kan vite hvor lang den er.
+
Det man så kan tro er at denne stringen nå har plass til 10 tegn. Det har den på et vis, men det siste tegnet må alltid være 0. Dette kalles null-byten, og er det som terminerer stringen slik at man kan vite hvor lang den er. I realiteten har derfor stringen kun plass til 9 bokstaver.
 +
 
 +
==== Eksempel: ====
  
 
  strcpy(string, "0123456789");
 
  strcpy(string, "0123456789");
Linje 52: Linje 53:
 
«Det er ingen feil i programmet, du ser jo at det kjører helt fint!» vil du kanskje svare. Men det er feil!
 
«Det er ingen feil i programmet, du ser jo at det kjører helt fint!» vil du kanskje svare. Men det er feil!
  
Det er ikke kjøringen av programmet som avgjør om det inneholder feil, det er det koden din som gjør. C-programmer kan kjøre tilsynelatende fint i lang tid med minnefeil, men plutselig skjer det noe spesielt slik at programmet kræsjer. Det flere opplever er at programmet kjører fint, mens den som skal rette oppgaven ikke får kjørt programmet fordi det kræsjer. På hjemmeeksamen hjelper det ikke at programmet kjørte da du testet det. Hvis det ikke kjører når eksamensretter tester blir det trekk. Kjør programmet ditt med valgrind slik som forklart her for å avdekke minne-feil i programmet ditt. Når programmet avslutter vil du også få en oversikt over hvor mye minne som ikke ble frigjort før programmet avsluttet.
+
Det er ikke kjøringen av programmet som avgjør om det inneholder feil, det er det koden din som gjør. C-programmer kan kjøre tilsynelatende fint i lang tid med minnefeil, men plutselig skjer det noe spesielt slik at programmet kræsjer. Det flere opplever er at programmet kjører fint, mens den som skal rette oppgaven ikke får kjørt programmet fordi det kræsjer. På hjemmeeksamen hjelper det ikke at programmet kjørte da du testet det. Hvis det ikke kjører når eksamensretter tester blir det trekk. Kjør programmet ditt med valgrind slik som forklart i [[Debugging]] for å avdekke minne-feil i programmet ditt. Når programmet avslutter vil du også få en oversikt over hvor mye minne som ikke ble frigjort før programmet avsluttet.

Nåværende revisjon fra 2. sep. 2010 kl. 00:22

Her er en kjapp oversikt over feil mange gjør i Oblig 1 og hjemmeeksamenene.

Innlevering av hjemmeeksamen inneholder navn på kandidaten

Innleveringen skal være anonym, så skriv ikke «Hilsen ditt_navn» i readme, eller «author ditt_navn» i kildekoden. Slikt vil gi trekk!

Kopiere en string

char *string1 = "Tullball";
char *string2 = string1;
printf("string1:%p\n", string1);
printf("string2:%p\n", string2);

Hvis du kjører koden ovenfor vil du se at de to variablene inneholder samme minneadresse. Det vil si at begge peker på samme sted i minnet, og følgelig samme data. Endringer i den ene vil føre til endringer i den andre.

For å lage en kopi av en string må man sette av et nytt minneområde, og kopiere stringen over i denne.

Allokere plass til en string

For å lagre en string må man ha plass i minnet, og det kan ordnes med malloc

char *string = malloc(10);

Det man så kan tro er at denne stringen nå har plass til 10 tegn. Det har den på et vis, men det siste tegnet må alltid være 0. Dette kalles null-byten, og er det som terminerer stringen slik at man kan vite hvor lang den er. I realiteten har derfor stringen kun plass til 9 bokstaver.

Eksempel:

strcpy(string, "0123456789");

vil kopiere de 10 tegnene minneområde som er allokert, i tillegg til at den legger '\0' (0) på den ellevte plassen. Det betyr at den skriver over 1 byte i minnet som ikke er allokert. Resultatet er at programme kan kræsje.

Les mer om null-byten

struct og nestepeker

Vi har følgende struct:

struct liste_elem {
    struct liste_elem *next;
    char *data;
};

Vi allokerer plass til en struct:

struct liste_elem *e = malloc(sizeof(struct liste_elem));

Vi har nå allokert plass i minnet, og adressen til dette minnet befinner seg i variabelen e. Når man allokerer plass vet man ikke hva minnet faktisk inneholder, så variablene neste og data kan inneholde hva som helst. Derfor er det viktig at man alltid gir dem en verdi. Spesielt neste-pekeren er det mange som glemmer:

e->next = NULL;

Minnelekasje og feil bruk av minnet

«Det er ingen feil i programmet, du ser jo at det kjører helt fint!» vil du kanskje svare. Men det er feil!

Det er ikke kjøringen av programmet som avgjør om det inneholder feil, det er det koden din som gjør. C-programmer kan kjøre tilsynelatende fint i lang tid med minnefeil, men plutselig skjer det noe spesielt slik at programmet kræsjer. Det flere opplever er at programmet kjører fint, mens den som skal rette oppgaven ikke får kjørt programmet fordi det kræsjer. På hjemmeeksamen hjelper det ikke at programmet kjørte da du testet det. Hvis det ikke kjører når eksamensretter tester blir det trekk. Kjør programmet ditt med valgrind slik som forklart i Debugging for å avdekke minne-feil i programmet ditt. Når programmet avslutter vil du også få en oversikt over hvor mye minne som ikke ble frigjort før programmet avsluttet.