Avatar billede rasmusbg Nybegynder
29. november 2004 - 15:20 Der er 9 kommentarer og
1 løsning

'Lagersegmentfejl' i forbindelse med pointere

Jeg sidder og hygger mig med Kernighan & Ritchie's fremragende bog om C, og jeg er kommet til kapitlet om pointere - nærmere bestemt er jeg kommet til det afsnit om pointere og tekststrenge.

Til dette afsnit er der en opgave, som går ud på at lave en funktion, der konkatenerer to strenge, og det skal være vha. pointere. Kildekoden har jeg kopieret ind her:

#include <stdio.h>

void cat(char *s, char *t);
void copy(char *s, char *t);

main() {
        char *s = "En streng";
        char *t = "er en streng";
        printf("%s\n",s);
        cat(s,t);
        printf("%s\n",s);
}

void cat(char *s, char *t) {
        while (*s++)
                ;
        copy(s,t);
}

void copy(char *s, char *t) {
        while (*s++ = *t++)
                ;
}

Når jeg prøver at køre programmet, får jeg at vide, at der er en lagersegmentfejl, og jeg har fundet ud af, at det er i forbindelse med while-løkken i cat(), at den opstår.

Mit problem er, at jeg er løbet tør for ideer til, hvordan jeg slipper af med den fejl. Specielt fordi bogen viser den copy()-funktion, jeg har, som et eksempel.
Avatar billede arne_v Ekspert
29. november 2004 - 15:23 #1
Prøv og erstat:

char *s = "En streng";

med

char s[100] = "En streng";
Avatar billede rasmusbg Nybegynder
29. november 2004 - 15:30 #2
Det hjalp sørme! Smid et svar :)

Der kommer lige et lille tillægsspørgsmål:

Er der virkelig ingen mulighed for at undgå at erklære s som et char-array?
Avatar billede arne_v Ekspert
29. november 2004 - 15:40 #3
Jo men jeg ved ikke om det er pænere.

char *s = (char *)malloc(100);
copy(s,"En streng");
Avatar billede arne_v Ekspert
29. november 2004 - 15:40 #4
svar
Avatar billede arne_v Ekspert
29. november 2004 - 15:42 #5
Og hvis du vil have en forklaring:

char *s = "En streng";

er en 4 byte pointer i ReadWrite sektion som peger på 10 bytes i ReadOnly sektion

char s[100] = "En streng";

er 100 bytes i ReadWrite sektion

Det virker ikke så godt at begynde at appende til noget plads som bruges til
noget andet i en ReadOnly sektion.
Avatar billede rasmusbg Nybegynder
29. november 2004 - 15:42 #6
Nej, det er ikke specielt meget pænere. Ihvertfald ikke når det er sådan et lille eksempel. Desuden er jeg heller ikke kommet til malloc endnu, så det venter jeg lige lidt med ;)
Avatar billede rasmusbg Nybegynder
29. november 2004 - 15:48 #7
Okay, så det vil sige, at en string constant i C er immutable (for at bruge et Javaudtryk)?
Avatar billede arne_v Ekspert
29. november 2004 - 15:55 #8
I alle nyere C compilere: ja. Muligvis kan man ændre det ved en compile option.

I gamle dage var det ikke tilfældet.

Men selvom den var i en ReadWrite sektion, så var det stadig et problem at skrive
ud over afslutningen af det.

Husk på at I Java for du en exception, hvis du bruger et out of range index. Men
i C kan du risikere bare at overskrive noget tilfældigt memory uden at få fejl
(og så får man en mystisk fejl et helt andet sted i koden).
Avatar billede rasmusbg Nybegynder
29. november 2004 - 15:59 #9
Det skal jeg prøve at huske!
Jeg skal vist lige vænne mig til, at der ikke er nogen, der holder mig i hånden og sørger for, at jeg ikke lave fejl i C, som der er i Java ;)

Tusind tak for hjælpen :)
Avatar billede arne_v Ekspert
29. november 2004 - 16:20 #10
Illustration:

#include <string.h>
#include <stdio.h>

struct ab
{
  char a[4];
  char b[4];
};

int main()
{
  struct ab s;
  strcpy(s.a,"ABC");
  strcpy(s.b,"DEF");
  printf("%s %s\n",s.a,s.b);
  s.a[3] = 'X';
  s.a[4] = 'Y';
  printf("%s %s\n",s.a,s.b);
  return 0;
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester