Sida 1 av 1
C: Matrisfråga
Postat: 06 mar 2012, 23:11
av Johnny Rosenberg
Ett enkelt exempel:
Kod: Markera allt
#include "stdio.h"
int main ()
{
int x;
double f[20];
for (x=0; x<30; x++){
f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
printf("f(%d)=%f\n", x, f[x]);
}
return 0;
}
Resultat:
f(0)=inf
f(1)=-1.623077
f(2)=-5.823077
f(3)=-7.023077
f(4)=-5.973077
f(5)=-2.823077
f(6)=2.376923
f(7)=9.605495
f(8)=18.851923
f(9)=30.110256
f(10)=43.376923
f(11)=58.649650
f(12)=75.926923
f(13)=95.207692
f(14)=116.491209
f(15)=139.776923
f(16)=165.064423
f(17)=192.353394
f(18)=221.643590
f(19)=252.934818
Segmenteringsfel
Helt väntat, inga konstigheter. Efter 20 varv i loopen hamnar vi utanför det definierade intervallet och får då följaktligen ett felmeddelande. Så långt allt väl.
Modifiering:
Kod: Markera allt
#include "stdio.h"
int main ()
{
/* int x; */
int r=20, x;
/* double f[20]; */
double f[r];
for (x=0; x<30; x++){ // Inga ändringar i resten av koden.
f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
printf("f(%d)=%f\n", x, f[x]);
}
return 0;
}
Resultat:
f(0)=inf
f(1)=-1.623077
f(2)=-5.823077
f(3)=-7.023077
f(4)=-5.973077
f(5)=-2.823077
f(6)=2.376923
f(7)=9.605495
f(8)=18.851923
f(9)=30.110256
f(10)=43.376923
f(11)=58.649650
f(12)=75.926923
f(13)=95.207692
f(14)=116.491209
f(15)=139.776923
f(16)=165.064423
f(17)=192.353394
f(18)=221.643590
f(19)=252.934818
f(20)=286.226923
f(21)=321.519780
f(22)=358.813287
f(23)=398.107358
f(24)=439.401923
f(25)=482.696923
f(26)=527.992308
Segmenteringsfel
Kan någon förklara varför f plötsligt kunde ha 27 element (0-26)?
Re: C: Matrisfråga
Postat: 06 mar 2012, 23:33
av mcNisse
Därför att du hade tur. Du kunde läsa 7 extra minnespositioner innan du kom till något olämpligt.
Det finns mao inga begränsningar i c hur långt du kan addressera i en array. Till slut kommer du till ett felaktigt värde.
jag är lite förvåndad att koden under fungerar. Det gjorde det inte när jag kodade c.
Re: C: Matrisfråga
Postat: 07 mar 2012, 17:59
av Johnny Rosenberg
mcNisse skrev:Därför att du hade tur. Du kunde läsa 7 extra minnespositioner innan du kom till något olämpligt.
Jag inte bara läste dem, jag tilldelade dem värden först.
Jag ska också tillägga att jag körde samma program tidigare men med r=10 och fick även då 7 extra minnespositioner, men när jag angav 10 direkt (utan att blanda in r), blev det 10 och inte ett öre extra, så jag vet inte riktigt om jag kan köpa resonemanget helt och fullt. Får nog testa några gånger till med olika värden för att se om det alltid blir just 7 positioner extra.
mcNisse skrev:Det finns mao inga begränsningar i c hur långt du kan addressera i en array. Till slut kommer du till ett felaktigt värde.
Fast det är ju jag själv som tilldelar värdena, eller menar du att jag förr eller senare försöker tilldela ett värde till en adress som är upptagen av något annat och att operativsystemet därför protesterar?
mcNisse skrev:jag är lite förvåndad att koden under fungerar. Det gjorde det inte när jag kodade c.
Kanske en ny ”feature”…
Fast varför skulle det egentligen inte fungera? Hur ofta vet man i förväg hur många element man behöver?
Men det är väl tänkt att man ska använda pekare och malloc() (dynamiska matriser), ett område som jag inte varit inne och känt på så mycket än. Känns som att det är upplagt för skapande av buggar, men man får väl försöka vara lite systematisk när man sitter där och försöker låta bli att klanta sig.
(Redigerat två gånger 2012-03-08 – hade klantat mig med taggarna, så ingen ny information är tillagd)
Re: C: Matrisfråga
Postat: 07 mar 2012, 18:04
av Johnny Rosenberg
Okej, nu har jag testat lite till med lite olika värden (200 och 2000 bland annat). Samma resultat varje gång: 7 extra om jag skriver ”double f[r]” jämfört med om jag använder en konstant istället för r. Provade även följande:
Kod: Markera allt
#include "stdio.h"
#define VAL 2000
int main ()
{
int r=VAL, x;
double f[VAL];
for (x=0; x<r+50; x++){
f[x]=x*x-5.7*x+1.0/13.0+3.0/x;
printf("f(%d)=%f\t%d\n", x, f[x], r);
}
return 0;
}
Resultatet blev detsamma som när jag angav 2000 direkt, föga förvånande, men jag ville testa ändå.
Nåja, oavsett vad det beror på, så är det ju ingen begränsning som hindrar mig på något sätt, möjligen skulle nackdelen kunna vara att kod som funkar ena dagen kanske inte funkar nästa dag om man slarvat med dimensioneringen och om det är som du säger.
Re: C: Matrisfråga
Postat: 07 mar 2012, 23:04
av mcNisse
Johnny Rosenberg skrev:Fast det är ju jag själv som tilldelar värdena, eller menar du att jag förr eller senare försöker tilldela ett värde till en adress som är upptagen av något annat och att operativsystemet därför protesterar?
Du tilldelar värden utanför den addressrymd som du har allokerat, du allokerar en array med 20 float. När du skriver bakom ditt allokerade utrymme är inte definierat vad som händer. Segmentaion violation, Bus error, wathever. Håll dig innanför det allokerade utrymmet. C hjälper inte till med att kontrollera vart du skriver.
Re: C: Matrisfråga
Postat: 08 mar 2012, 11:58
av Bowmore
Märkligt att kompilatorn (gcc?) accepterar
då en array har en fix storlek som sätts vid kompileringen.
Koden är knappast portabel mellan kompilatorer.
Alltså, storleken ska anges som en konstant och inte med en värdesatt variabel.
Re: C: Matrisfråga
Postat: 08 mar 2012, 19:32
av Johnny Rosenberg
Bowmore skrev:Märkligt att kompilatorn (gcc?) accepterar
då en array har en fix storlek som sätts vid kompileringen.
Koden är knappast portabel mellan kompilatorer.
Alltså, storleken ska anges som en konstant och inte med en värdesatt variabel.
Så i mitt fall, när jag vill kunna ändra matrisens storlek, så är detta alltså inte en framkomlig väg?
Re: C: Matrisfråga
Postat: 08 mar 2012, 20:53
av HakanS
Johnny Rosenberg skrev:Så i mitt fall, när jag vill kunna ändra matrisens storlek, så är detta alltså inte en framkomlig väg?
Nej, arrayens storlek bestäms vid deklareringen och kan sedan inte ändras.
Re: C: Matrisfråga
Postat: 09 mar 2012, 00:24
av Bowmore
Behöver du en "dynamisk" array så skapar du den (allokerar minne) i runtime med malloc, ändrar storleken med realloc och sen frigör minnet med free innan du avslutar programmet, så du inte skapar minnesläckor.
Re: C: Matrisfråga
Postat: 09 mar 2012, 22:33
av Johnny Rosenberg
Bowmore skrev:Behöver du en "dynamisk" array så skapar du den (allokerar minne) i runtime med malloc, ändrar storleken med realloc och sen frigör minnet med free innan du avslutar programmet, så du inte skapar minnesläckor.
Det var det jag misstänkte… Tackar för informationen!
Har lite följdfrågor på detta, men jag ska inte ställa dem innan jag letat efter svaren själv först och inte lyckats hitta dem…