/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
Hukommelsesfejl i simpelt program
Fra : Anders Ebbesen


Dato : 18-12-00 19:21

Halløj!

Jeg arbejder i VC++ 5.0 og følger bogen "Beginning VC++ 5.0" fra Wrox.

Nedenstående kode giver mig en fejl, når jeg forsøger at eksekvere det inde
i VC++. Det giver ingen problemer hvis jeg kører det direkte fra .exe-filen.
Når jeg kører det fra VC++ går VC++ ned, og programmet kører videre.

!------------------------!
#include <iostream.h>
#include <iomanip.h>

int main()
{
const int MAX = 20;
double gas[MAX];
long miles[MAX];
int count = 0;
char indicator = 'n';

for (count = 0; count < MAX; count++)
{
cout << endl
<< "Enter gas quantity: ";
cin >> gas[count];
cout << "Enter odometer reading: ";
cin >> miles[count];

cout << "Do you want to enter another(y or n)? ";
cin >> indicator;

if (indicator == 'n' || indicator == 'N')
break;
}

if (count < 1)
{
cout << endl
<< "Sorry - at least two readings are necessary.";
return 0;
}

for(int i=1; i <= count; i++)
cout << endl
<< setw(2) << i << "."
<< "Gas purchased = " << gas[i] << " gallons"
<< " resulted in "
<< (miles[i] - miles[i-1])/gas[i] << " miles per gallon.";

cout << endl;
return 0;
}
!------------------------!

Det er første script hvor jeg gør brug af arrays, men jeg ville nu ikke mene
at det skulle give nogen problemer at afsætte den smule RAM som skal bruges
til at gemme de two arrays.

På forhånd tak for enhver hjælp.

--
Anders Ebbesen
"You could be searching for a personnel file for someone who is over 21 but
under 35, female with a college degree, unmarried and speaks Hindi or Urdu.
Defining a test for this could involve the mother of alle ifs." - Beg. VC++



 
 
Anders Ebbesen (18-12-2000)
Kommentar
Fra : Anders Ebbesen


Dato : 18-12-00 20:23


"Anders Ebbesen" <anders@ebbesen.org> skrev i en meddelelse
news:oAs%5.7712$9t1.55140@twister.sunsite.dk...
> Halløj!
[SNIP]
> const int MAX = 20;
> double gas[MAX];
> long miles[MAX];
[SNIP]

Løste problemet ved at lave ovenstående om til

double gas[MAX] = {0};
long miles[MAX] = {0};

hvilket vel som sådan altid er en god idé?

(medmindre man naturligvis har brug for en random function..!?)

--
Anders Ebbesen
"You could be searching for a personnel file for someone who is over 21 but
under 35, female with a college degree, unmarried and speaks Hindi or Urdu.
Defining a test for this could involve the mother of alle ifs." - Beg. VC++




N/A (18-12-2000)
Kommentar
Fra : N/A


Dato : 18-12-00 21:10



Anders Ebbesen (18-12-2000)
Kommentar
Fra : Anders Ebbesen


Dato : 18-12-00 21:10

"Richard Flamsholt" <richard@flamsholt.dk> skrev i en meddelelse
news:n8qs3t8s4bs7u5jga5t3a07f1uqt7gs7mu@4ax.com...
> "Anders Ebbesen" <anders@ebbesen.org> skrev:
> >Løste problemet ved at lave ovenstående om til
> >
> >double gas[MAX] = {0};
> >long miles[MAX] = {0};
> >
> >hvilket vel som sådan altid er en god idé?
>
> Næh. Kun hvis det er nødvendigt.

Okay, men jeg troede det var nødvendigt for at tømme de memory-slots jeg
kommer til at bruge i arrayet?

Jeg skrev for sjov et lille script:

----
[Snip standard-ting]
int Junk[5];
for (i=0; i<5; i++)
cout << setw(12) << Junk[i];
[Snip standard-ting]
----

Og jeg fik nogen sjove tal spyttet ud, dvs. de tal som allerede var på de
hukommelsespladser som arrayet gjorde brug af.

> En af mine personlige kæpheste er, at man ikke bør initialisere alskens
> variabler til 0 fordi "så virker programmet". Man skal vide, hvilke der
> skal initialiseres, til hvad og hvorfor. Mange x=0 bunder egentlig i, at
> programmøren ikke helt aner, hvad der foregår.

Uden tvivl, jeg er endnu ikke selv stærk nok i C++ til at vurdere dette.

> Næh, det var nok bedre at ændre slutbetingelsen i løkken
>
> > for(int i=1; i <= count; i++)
> > [snip]
> > << (miles[i] - miles[i-1])/gas[i] << " miles per gallon.";
>
> - til at lyde "i < count". Ellers refererer du ud over såvel miles[] som
> gas[] arrayet. gas[20] er måske en ulovlig double, eller ligefrem 0, og
> så har du balladen i divisionen.

Hvordan får I count til at komme op på 20?

Jeg har løkken "for (count = 0; count < MAX; count++)" og da MAX er sat til
20 kommer count vel kun op på 19?

--
Anders Ebbesen
"You could be searching for a personnel file for someone who is over 21 but
under 35, female with a college degree, unmarried and speaks Hindi or Urdu.
Defining a test for this could involve the mother of alle ifs." - Beg. VC++



Martin Moller Peders~ (18-12-2000)
Kommentar
Fra : Martin Moller Peders~


Dato : 18-12-00 21:41

In <Aau%5.8294$9t1.59886@twister.sunsite.dk> "Anders Ebbesen" <anders@ebbesen.org> writes:

>Hvordan får I count til at komme op på 20?

>Jeg har løkken "for (count = 0; count < MAX; count++)" og da MAX er sat til
>20 kommer count vel kun op på 19?

En for-loekke bliver normalt omsat til en while-loekke.
Dvs. din for (count=0; count<MAX; count++) ...; bliver til:

count=0;
while (count<MAX) {
...;
count++;
}

Saa naar count=19 bliver ... udfoert og count bliver talt op igen til 20.
Saa udfoeres while-loekkens test igen og denne gang er den falsk.

btw. saa kaldes denne omformning af en for-loekke til en while-loekke for
syntaktisk sukker.

/Martin




N/A (19-12-2000)
Kommentar
Fra : N/A


Dato : 19-12-00 13:07



Per Abrahamsen (19-12-2000)
Kommentar
Fra : Per Abrahamsen


Dato : 19-12-00 13:07

fuzz01@spamfilter.dk (Anders Bo Rasmussen) writes:

> >In <Aau%5.8294$9t1.59886@twister.sunsite.dk> "Anders Ebbesen" <anders@ebbesen.org> writes:

> >>Jeg har løkken "for (count = 0; count < MAX; count++)" og da MAX er sat til

[ ... ]
> Hvis den gør det, må der da være en fejl i compileren, da count ikke
> kan "ses" uden for for-løkken i følge standarden.

Jo, hvis man erklærer den udenfor for-løkken, som i Anders' eksempel.


Troels Thomsen (21-12-2000)
Kommentar
Fra : Troels Thomsen


Dato : 21-12-00 00:19

>
> Hvis den gør det, må der da være en fejl i compileren, da count ikke kan
"ses"
> uden for for-løkken i følge standarden.
>

MSVC 6 fungerer stadig ( non std ) sådan :

for (int i = 0 ; i<10 ; i++) {} ;
for (int i = 0 ; i<10 ; i++) {} ;

error C2374: 'i' : redefinition; multiple initialization
: see declaration of 'i'






Richard Flamsholt (18-12-2000)
Kommentar
Fra : Richard Flamsholt


Dato : 18-12-00 22:51

"Anders Ebbesen" <anders@ebbesen.org> skrev:
>Okay, men jeg troede det var nødvendigt for at tømme de memory-slots jeg
>kommer til at bruge i arrayet?

Variable er reelt bytes. Bytes indeholder altid et tal mellem 0-255. Dvs
at dine tal-variabler altid indeholder noget. De kan ikke "tømmes", men
kun sættes til forskellige værdier. Som udgangspunkt er variabelværdier
tilfældige, som du også selv fandt ud af:

>Jeg skrev for sjov et lille script:
>Og jeg fik nogen sjove tal spyttet ud, dvs. de tal som allerede var på de
>hukommelsespladser som arrayet gjorde brug af.


Spørgsmålet er så, hvorvidt du ønsker at dine variabler som udgangspunkt
indeholdet det relativt "pæne" tal 0, eller et helt tilfældigt tal. Hvis
du aldrig kikker på det u-initialiserede indhold er det ret ligegyldigt
hvad den værdi er, ikke? Sært nok har nogle programmører det alligevel
bedre (pga usikkerhed mht koden?), hvis de værdier, de egentlig ikke har
tænkt sig at kikke på, er 0.

Dit program er et strålende eksempel på, at det er unødvendigt:

   for (count = 0; count < MAX; count++) {
    cin >> gas[count];
    ...
   }

Når løkken er færdig vil gas[0] til og med gas[count-1] indeholde de
indtastede værdier - og de andre er man fløjtende ligeglad med.

Men gør unødvendig initialisering da nogen skade? På sin vis, ja. Det er
nemlig altid forvirrende med unødvendig kode. Andre programmører, og dig
selv om et år, vil kikke på det og undre sig over, om der er en dybere
mening. Mange vil ikke turde fjerne koden, og derfor kan forvirrende og
sære kodestumper overleve år efter år.

Den eneste fordel er, at man sikrer at uinitialiserede variabler opfører
sig ens hver gang programmet kører, og det kan fremprovokere fejl. Men
det er en dårlig undskyldning for at lave kode, man ikke helt forstår.


>Uden tvivl, jeg er endnu ikke selv stærk nok i C++ til at vurdere dette.

Det gælder for alle programmeringssprog.


>Jeg har løkken "for (count = 0; count < MAX; count++)" og da MAX er sat til
>20 kommer count vel kun op på 19?

Løkken afbrydes, når "count < MAX" ikke længere er sandt. Det sker når
count er MAX (eller >= MAX), dvs 20.

--
Richard Flamsholt
richard@flamsholt.dk - www.richard.flamsholt.dk

Per Abrahamsen (19-12-2000)
Kommentar
Fra : Per Abrahamsen


Dato : 19-12-00 12:49

Richard Flamsholt <richard@flamsholt.dk> writes:

> Mange x=0 bunder egentlig i, at
> programmøren ikke helt aner, hvad der foregår.

Og andre i at compileren er for dum til at indse at der ikke er nogen
code path som leder frem til at variablen bliver brugt uden at være
initialiseret, og derfor synes den skal brokke sig.

Igor V. Rafienko (18-12-2000)
Kommentar
Fra : Igor V. Rafienko


Dato : 18-12-00 20:34

* Anders Ebbesen

> Nedenstående kode giver mig en fejl, når jeg forsøger at eksekvere
> det inde i VC++. Det giver ingen problemer hvis jeg kører det
> direkte fra .exe-filen. Når jeg kører det fra VC++ går VC++ ned, og
> programmet kører videre.


Nedenstående kode illustrerer _veldig_ godt hvorfor C-style arrays er
Feil Ting[tm] i C++. Jo før du begynner å bruke vector<>, desto mer
innsats og tid sparer du.


> #include <iostream.h>
> #include <iomanip.h>


#include <iostream>
#include <iomanip>


> int main()
> {
> const int MAX = 20;
> double gas[MAX];
> long miles[MAX];
> int count = 0;


Bruk unsigned variable når signed ikke gir mening (som fx. i tilfellet
med indekser).


> char indicator = 'n';
>
> for (count = 0; count < MAX; count++)
> {
> cout << endl
> << "Enter gas quantity: ";
> cin >> gas[count];
> cout << "Enter odometer reading: ";
> cin >> miles[count];
>
> cout << "Do you want to enter another(y or n)? ";
> cin >> indicator;
>
> if (indicator == 'n' || indicator == 'N')
> break;
> }


På dette punktet kan man stille seg et spørsmål ang. verdien av count.
Dersom man faktisk skrev 20 entries, så er count 20.


> if (count < 1)
> {
> cout << endl
> << "Sorry - at least two readings are necessary.";
> return 0;
> }
>
> for(int i=1; i <= count; i++)


Og her vil du indeksere ett hakk for langt ut, i tilfellet beskrevet
over. Og en annen ting -- hvorfor indekserer du fra 1 og ikke fra 0?


> cout << endl
> << setw(2) << i << "."
> << "Gas purchased = " << gas[i] << " gallons"
> << " resulted in "
> << (miles[i] - miles[i-1])/gas[i] << " miles per gallon.";


og dersom gas[i] er 0? Forresten, hvordan reagerer VC++ på "division
by zero"?


> Det er første script hvor jeg gør brug af arrays, men jeg ville nu
> ikke mene at det skulle give nogen problemer at afsætte den smule
> RAM som skal bruges til at gemme de two arrays.


Nei, det er nok ikke dette som er problemet.





ivr
--
The C language combines all the power of assembly language with all
the ease-of-use of assembly language.
      -- P. van der Linden "Expert C Programming"

Anders Ebbesen (18-12-2000)
Kommentar
Fra : Anders Ebbesen


Dato : 18-12-00 21:05

"Igor V. Rafienko" <igorr@ifi.uio.no> skrev i en meddelelse
news:xjvae9t8qy6.fsf@ganglot.ifi.uio.no...
> * Anders Ebbesen
>
> > Nedenstående kode giver mig en fejl, når jeg forsøger at eksekvere
> > det inde i VC++. Det giver ingen problemer hvis jeg kører det
> > direkte fra .exe-filen. Når jeg kører det fra VC++ går VC++ ned, og
> > programmet kører videre.

Jeg vil i øvrigt lige nævne at det ikke er "mit" program, det er et program
som mest en ment som et eksempel på brug af arrays i c++. Det er fra bogen
Beginning VC++ 5.0 fra Wrox.

> Nedenstående kode illustrerer _veldig_ godt hvorfor C-style arrays er
> Feil Ting[tm] i C++. Jo før du begynner å bruke vector<>, desto mer
> innsats og tid sparer du.

Okay.

> > #include <iostream.h>
> > #include <iomanip.h>
>
> #include <iostream>
> #include <iomanip>

Hvis jeg gør sådan her får jeg en masse fejl i VC++5.0, 'cout': undeclared
identifier, '<<': bad right operand mv.

> > int main()
> > {
> > const int MAX = 20;
> > double gas[MAX];
> > long miles[MAX];
> > int count = 0;
>
> Bruk unsigned variable når signed ikke gir mening (som fx. i tilfellet
> med indekser).

God idé.

> På dette punktet kan man stille seg et spørsmål ang. verdien av count.
> Dersom man faktisk skrev 20 entries, så er count 20.

Count kan max være 19 og hvis man giver "indicator" værdien 'n' eller 'N'
kommer count ikke op på 19.

> > if (count < 1)
> > {
> > cout << endl
> > << "Sorry - at least two readings are necessary.";
> > return 0;
> > }
> >
> > for(int i=1; i <= count; i++)
>
>
> Og her vil du indeksere ett hakk for langt ut, i tilfellet beskrevet
> over.

Count kan max være 19, de to arrays er defineret til 20 i størrelse. Det
burde være 0 til 19?

> Og en annen ting -- hvorfor indekserer du fra 1 og ikke fra 0?

Hvis folk kun indtaster ét sæt gas og miles er det ikke interessant at
udregne hvor mange miles man kører for hver gas, da miles i dette tilfælde
er tænkt som et odometer.

> > cout << endl
> > << setw(2) << i << "."
> > << "Gas purchased = " << gas[i] << " gallons"
> > << " resulted in "
> > << (miles[i] - miles[i-1])/gas[i] << " miles per gallon.";
>
> og dersom gas[i] er 0? Forresten, hvordan reagerer VC++ på "division
> by zero"?

Programmet skulle blot teste array-funktionen, der er ikke nogen sønderlig
mening eller noget formål med scriptet, og errorhandling er naturligvis ikke
lagt ind.

Jeg løste problemet ved at initialisere de to arrays i stedet for blot at
definere dem.

--
Anders Ebbesen
"You could be searching for a personnel file for someone who is over 21 but
under 35, female with a college degree, unmarried and speaks Hindi or Urdu.
Defining a test for this could involve the mother of alle ifs." - Beg. VC++



N/A (18-12-2000)
Kommentar
Fra : N/A


Dato : 18-12-00 21:49



Anders Ebbesen (18-12-2000)
Kommentar
Fra : Anders Ebbesen


Dato : 18-12-00 21:49

"Igor V. Rafienko" <igorr@ifi.uio.no> skrev i en meddelelse
news:xjvg0jljwrk.fsf@helgrind.ifi.uio.no...
> * Anders Ebbesen
> > > > #include <iostream.h>
> > > > #include <iomanip.h>
> > >
> > > #include <iostream>
> > > #include <iomanip>
> >
> > Hvis jeg gør sådan her får jeg en masse fejl i VC++5.0, 'cout':
> > undeclared identifier, '<<': bad right operand mv.
>
> Helt korrekt: det finnes ingen identifier cout i det globale
> navnerommet. Det finnes dog "std::cout".

Giver den bedre performance end <iostream.h> og cout eller?

> > > På dette punktet kan man stille seg et spørsmål ang. verdien av
> > > count. Dersom man faktisk skrev 20 entries, så er count 20.
> >
> > Count kan max være 19 og hvis man giver "indicator" værdien 'n'
> > eller 'N' kommer count ikke op på 19.
>
> Nope, count kan være lik MAX i koden din~Wfra boken. Tenk deg litt om.

Så så, jeg troede ikke at "for (count = 0; count < 20; count++)" ville give
20. Troede den stoppede når den nåede grænsen (19) og så ikke lagde mere
til.

Går den så op på 21 hvis man bruger "for (count = 0; count <= 20; count++)"?

> > Count kan max være 19, de to arrays er defineret til 20 i størrelse.
> > Det burde være 0 til 19?
>
> I og med at count vil faktisk kunne nå opptil og med 20, vil det gå
> galt.

Det ved jeg så nu.

> > Jeg løste problemet ved at initialisere de to arrays i stedet for
> > blot at definere dem.
>
> Da løste du ikke problemet.

Uhm, okay, men inden jeg indsatte "= {0}" ved arraydefinitionerne gik VC++
ned ved programstart, det gjorde den ikke efterfølgende, men nu ser jeg at
der kunne opstå et problem, såfremt man fyldte de to arrays "for meget".

--
Anders Ebbesen
"You could be searching for a personnel file for someone who is over 21 but
under 35, female with a college degree, unmarried and speaks Hindi or Urdu.
Defining a test for this could involve the mother of alle ifs." - Beg. VC++



Igor V. Rafienko (18-12-2000)
Kommentar
Fra : Igor V. Rafienko


Dato : 18-12-00 22:09

* Anders Ebbesen

[snip]

> > Helt korrekt: det finnes ingen identifier cout i det globale
> > navnerommet. Det finnes dog "std::cout".
>
> Giver den bedre performance end <iostream.h> og cout eller?


Who the f... cares? Er du bekymret for performance finnes det masse
andre hvor man skal optimalisere enn cout (særlig med tanke på at cout
er ofte ment til å være stedet hvor output for mennesker havner hen
(jada, jeg er klar over pipes)). Språkdefinisjonen _krever_ at cout
skal bo i navnerommet std (ahem: jeg må innrømme at jeg er litt sløv
med akkurat det der selv noen ganger, men det er nå så).

[snip]


> Så så, jeg troede ikke at "for (count = 0; count < 20; count++)"
> ville give 20. Troede den stoppede når den nåede grænsen (19) og så
> ikke lagde mere til.


Helt korrekt -- inni løkkekroppen er count alltid mindre enn 20. Når
du går ut av løkken kan count være lik 20.


> Går den så op på 21 hvis man bruger "for (count = 0; count <= 20;
> count++)"?


Helt korrekt (hint: "increment step" skjer etter at kroppen er utført
men før testen).

[snip]





ivr
--
The C language combines all the power of assembly language with all
the ease-of-use of assembly language.
      -- P. van der Linden "Expert C Programming"

Per Abrahamsen (19-12-2000)
Kommentar
Fra : Per Abrahamsen


Dato : 19-12-00 12:57

"Anders Ebbesen" <anders@ebbesen.org> writes:

> "Igor V. Rafienko" <igorr@ifi.uio.no> skrev i en meddelelse
> news:xjvae9t8qy6.fsf@ganglot.ifi.uio.no...
> > * Anders Ebbesen
> >
> > > Nedenstående kode giver mig en fejl, når jeg forsøger at eksekvere
> > > det inde i VC++. Det giver ingen problemer hvis jeg kører det
> > > direkte fra .exe-filen. Når jeg kører det fra VC++ går VC++ ned, og
> > > programmet kører videre.
>
> Jeg vil i øvrigt lige nævne at det ikke er "mit" program, det er et program
> som mest en ment som et eksempel på brug af arrays i c++. Det er fra bogen
> Beginning VC++ 5.0 fra Wrox.
>
> > Nedenstående kode illustrerer _veldig_ godt hvorfor C-style arrays er
> > Feil Ting[tm] i C++. Jo før du begynner å bruke vector<>, desto mer
> > innsats og tid sparer du.
>
> Okay.
>
> > > #include <iostream.h>
> > > #include <iomanip.h>
> >
> > #include <iostream>
> > #include <iomanip>
>
> Hvis jeg gør sådan her får jeg en masse fejl i VC++5.0, 'cout': undeclared
> identifier, '<<': bad right operand mv.

Indsæt en

using namespace std;

bagefter.

Fordelen ved at bruge formerne uden ".h" er at det er dem der står i
standarden, så din kode er mere fremtidssikret. Lige nu er der dog
flere compilere der understøtter formerne med ".h" end uden, men det
vil ændre sig med tiden.

Bemærk at den compiler Igor benytter endnu ikke understøtter
standarden, det er derfor hans kode virker selv om han glemte at
skrive "std::" foran cout (he he).

Det headers er normalt lige effektive, en typisk implementering af
'iostream.h' er:

// iostream.h

#include <iostream>
using namespace std;

// iostream.h ends here

Thomas Schulz (22-12-2000)
Kommentar
Fra : Thomas Schulz


Dato : 22-12-00 23:50

> Nedenstående kode giver mig en fejl, når jeg forsøger at eksekvere det
inde
> i VC++. Det giver ingen problemer hvis jeg kører det direkte fra
..exe-filen.
> Når jeg kører det fra VC++ går VC++ ned, og programmet kører videre.
Nu er jeg ganske vist ikke C++ guru (og med forbehold for jeg har overset
noget, da jeg er ret stenet), men..

her gør du:
> for (count = 0; count < MAX; count++) // fra 0-19 i arrayet
men du gør også længere nede:
> for(int i=1; i <= count; i++) // fra 1-20
Dne arrays er initialiseret:
> double gas[MAX]; // 0-19
> long miles[MAX]; // 0-19


Godt nok kan man i C++ lave totalt vildt ulækre ting hvis man virkelig vil
udfordre lykken (her snakker jeg ikke om de IMO ikke-slemme eksempler der
før har været givet i gruppen under tidligere diskussioner i andre
sammenhænge), men
ovenstående vil i hvert fald typisk føre en fejl med sig i en del sprog (i
det du accessor [20]).


Thomas



Søg
Reklame
Statistik
Spørgsmål : 177552
Tips : 31968
Nyheder : 719565
Indlæg : 6408847
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste