Vanlige feil i oblig og hjemmeeksamen

Fra mn/ifi/INF1060
Hopp til: navigasjon, søk

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.