Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Segmentation error ?  (gelezen 1593 keer)

Offline Joshua822

  • Lid
Segmentation error ?
« Gepost op: 2009/04/09, 23:42:51 »
Om mezelf vertrouwt te maken met loops ben ik in C een script voor het uitrekenen van machten aan het schrijven. Script werkte prima. Dus wou ik ook dat ik zelf zou kunnen ingeven welke macht uitgerekend moet worden.

Dus schreef ik dit.

Citaat
#include <stdio.h>

main(void){

int a,b,i,x;
printf("Grondtal:");
scanf("%d",i);
printf("Exponent:");
scanf("%d",b);
printf("%d",b);
x = i;
 
for ( a = 0; a < b--; a++ ){
 i = i * x;
}

printf("%s %d","Uitkomst:", i);
getchar();
return 0;

}

Echter, als ik dit uitvoer en ik typ een getal bij exponent en druk dan op enter krijg ik in beeld "segmentation error".

Segmentatie heeft iets te maken met verdelen. Maar ik zie niet waar dit van toepassing zou kunnen zijn. Het moet echter wel voor de for loop gebeuren. Want deze code verschilt niet van het script zonder user input oundersteuning. Ik heb al zitten zoeken op internet en ik heb mijn brein al lam gedacht over wat ik hier in hemelsnaam fout doe.

Help, alsjeblieft ? :(

Offline charclo

  • Lid
Re: Segmentation error ?
« Reactie #1 Gepost op: 2009/04/10, 00:05:58 »
Volgens mij klopt deze regel niet:
for ( a = 0; a < b--; a++ ){
probeer dit eens te veranderen naar iets als:
for ( a = 0; a < (b - 1); a++ ){

Je kan ook eens proberen met een debugger je code te doorlopen en te kijken waar je de segmentation error (fout in je programma) krijgt. Je kan hiervoor gdb gebruiken maar hier heb ik geen ervaring mee.
« Laatst bewerkt op: 2009/04/10, 00:08:16 door charclo »
HP Pavilion dv6660eb - Intel Core 2 Duo T7250 2 GHz - 2 GB ram - Nvidia GeForce 8400M GS 128 MB --> Dualboot Ubuntu en Windows Vista
P4 2.6 GHz - 1GB ram - NVIDIA GS7600 - 20 inch Benq widescreen --> Dualboot Ubuntu en Windows XP

Offline track

  • Lid
Re: Segmentation error ?
« Reactie #2 Gepost op: 2009/04/10, 01:17:24 »
Hoi Joshua,

een "segmentation fault" betekent in ieder geval dat een variabele probeert uit te breken
naar een plaats in het geheugen waar zij niet behoort.

Nu is de vraag waar dat gebeurt.  Een verdachte is zeker wat charclo al zei.
Ik weet ook niet wat er gebeurt als je de grens van een for-lus verandert (verandert zij eigenlijk per rondje ?).
Is dat niet een constante ?   Zoiets doe je normaal niet, mogelijkheid 1 voor een SegFault dus.

Wat ik ook iets ongelukkig is, zelfs het resultaat sla je in een integer op.  Normaal zou je een real of double pakken.
Een integer bevat (afhankelijk van het systeem) maar 16 of 32 bits.
Zou hij dus ooit boven de  4294967295 lopen, wat gebeurt dan ?  Komt er een SegFault of zal hij gewoon overlopen ?

track

Offline Joshua822

  • Lid
Re: Segmentation error ?
« Reactie #3 Gepost op: 2009/04/10, 14:36:14 »
Citaat
#include <stdio.h>

main(void){

float a,b,i,x;
printf("Grondtal:");
scanf("%1.0f",i);
printf("Exponent:");
getchar();
scanf("%1.0f",b);
x = i;
 
for ( a = 0; a < b--; a++ ){
 i = i * x;
}

printf("%s %1.0f","\n Uitkomst:", i);
getchar();
return 0;

}


Ik heb nu alle integers vervangen door floating points. Maar, nu krijg ik elke keer als ik hetzelfde ingeef een andere output. En dit is in de 100 keer dat ik het veranderd heb en uitgevoerd heb nog niet een keer geweest wat het zou moeten zijn. Iemand enige raad ?

Citaat
Grondtal:2
Exponent:2

 Uitkomst: -2

Dat kan toch niet ?

Offline Kev

  • Lid
Re: Segmentation error ?
« Reactie #4 Gepost op: 2009/04/10, 14:44:52 »
Ik zou niet met floats werken ten eerste, probeer het eens door gebruik te maken van doubles, laat iets weten wat er gebeurd met doubles.
All Hail Lelouch, The 99th Emperor of Britannia
All Hail Lelouch! All Hail Lelouch!
Iedereen heeft het recht op mijn waarheid, zo wees geprezen.

Offline charclo

  • Lid
Re: Segmentation error ?
« Reactie #5 Gepost op: 2009/04/10, 15:38:13 »
Ik denk dat ik je probleem gevonden heb:
scanf("%d",i);
moet zijn:
scanf("%d",&i);
HP Pavilion dv6660eb - Intel Core 2 Duo T7250 2 GHz - 2 GB ram - Nvidia GeForce 8400M GS 128 MB --> Dualboot Ubuntu en Windows Vista
P4 2.6 GHz - 1GB ram - NVIDIA GS7600 - 20 inch Benq widescreen --> Dualboot Ubuntu en Windows XP

Offline charclo

  • Lid
Re: Segmentation error ?
« Reactie #6 Gepost op: 2009/04/10, 15:41:29 »
Ik heb dit uitgetest en het lijkt te werken:
#include <stdio.h>

main(void){

int a,b,i,x;
printf("Grondtal:");
scanf("%d",&i);
printf("Exponent:");
scanf("%d",&b);
x = i;
 
for ( a = 0; a < b--; a++ ){
 i = i * x;
}

printf("Uitkomst: %d \n", i);
getchar();
return 0;

}

toch zou ik dit nooit doen:

for ( a = 0; a < b--; a++ ){

het ziet er niet zo proper uit.

Ook kan je om een exponent te berekenen gewoon pow(base, exponent) gebruiken.
« Laatst bewerkt op: 2009/04/10, 15:45:18 door charclo »
HP Pavilion dv6660eb - Intel Core 2 Duo T7250 2 GHz - 2 GB ram - Nvidia GeForce 8400M GS 128 MB --> Dualboot Ubuntu en Windows Vista
P4 2.6 GHz - 1GB ram - NVIDIA GS7600 - 20 inch Benq widescreen --> Dualboot Ubuntu en Windows XP

Offline Joshua822

  • Lid
Re: Segmentation error ?
« Reactie #7 Gepost op: 2009/04/10, 16:04:12 »
Zeer hartelijk bedankt. Het werkt !

Ik wist dat het met pow kon. Maar het berekenen van een macht/vierkantswortel leek me echt een ideale oefening voor een beginner die de for loop onder de knie wil krijgen.

Maar waarvoor dient die "&" in het tweede argument van de scanf functie dan als ik vragen mag ?

Offline idefix

  • Lid
Re: Segmentation error ?
« Reactie #8 Gepost op: 2009/04/10, 16:24:19 »
Die & is de adres-operator. Die geeft dus het adres in het geheugen van een variabele weer.
Je moet het geheugen opvatten als een enorme kast met een enorm aantal vakjes. Elk vakje heeft een uniek nummer (adres). Anders zou de computer niet op ondubbelzinnige wijze het geheugen kunnen gebruiken.
Als je dus een int i declareert, reserveer je een vakje in het geheugen waar je die i instopt.Het adres (uniek nummer van dat vakje kun je krijgen door &i op te vragen.
Dat adres stop je meestal in een pointer (een wijzer, meerbepaald een wijzer naar een bepaald geheugenvakje).
Een pointer wordt met een * gedeclareerd. Bijvoorbeeld

int * p;

declareert een variabele p van het type "pointer naar integer". Daar kun je nu het adres van een integer in stoppen.

Probeer eens volgende code:

#include <stdio.h>
main(){
  int i = 7;
  int * p;
  p = &i;
  printf("%s%d\n%s%u\n", "i heeft de waarde: ", *p, "i staat op adres: ", p);
}

De variabele p bevat dus het adres. Om te weten wat de waarde is van de variable op dat adres, gebruik je *p, zoals in het print-statement. (dit heet dereferencing)
De vraag die je nu gaat stellen, is deze: wat is het nut hiervan? Wel, pointers laten toe om sneller het geheugen te benaderen. Vooral bij grote arrays (lijsten van eenzelfde type) speelt dat een rol. Gelinkte lijsten maken ook veel gebruik van pointers. Eigenlijk zijn pointers een basisconcept van C. (ook van Java bvb maar dan achter de schermen).
Ik hoop dat deze uitleg een beetje opheldert. Het is nogal abstract allemaal, maar je moet het maar eens traag herlezen en goed laten doordringen.
En als antwoord op uw vraag: de functie scanf neemt een adres als tweede argument.

« Laatst bewerkt op: 2009/04/10, 16:35:23 door idefix »
Support bacteria. They're the only culture some people have.

Offline idefix

  • Lid
Re: Segmentation error ?
« Reactie #9 Gepost op: 2009/04/10, 16:32:36 »
Eigenlijk is mijn uitleg te simplistisch hierboven. Voor de volledigheid:

een pointer verwijst naar het adres van de eerste byte van een variabele. Een int wordt bijvoorbeeld vaak opgeslagen in 4 bytes. Om te weten hoeveel bytes jouw systeem toekent aan een bepaald type variabele, kun je de sizeof operator gebruiken, bijvoorbeeld:

printf ("int: %d  bytes\n", sizeof(int));
Je kan de int tussen haakjes vervangen door char, long, double, long double, float, ...


Support bacteria. They're the only culture some people have.

Offline Joshua822

  • Lid
Re: Segmentation error ?
« Reactie #10 Gepost op: 2009/04/10, 16:35:30 »
Zeer erg bedankt voor de uitleg Idefix ! Maakt veel duidelijk. Ik vind het ook niet vervelend, efficient problemen oplossen is goed problemen oplossen ;)