C++; Program fungerar men kraschar

Trädvy Permalänk
Medlem
Registrerad
Jan 2017

C++; Program fungerar men kraschar

Hellu!
Har gjort ett program där användaren bestämmer antalet mätningar som sparas i en array. Användaren får sedan skriva in värdet på varje index. Programmet skriver sedan ut hela listan bara för att visa att det funkar. Inga konstigheter, fungerar som det ska. Jag lägger sedan till en uträkning för medelvärde. Även denna beräkning fungerar. Problemet är bara att kompilatorn/programmet kraschar när det körs klart. Är det något jag gör fel i koden? Kolla i sista if loopen, där medelvärdet görs. Tar man bort denna så kraschar inte programmet. Tack tack för hjälp

#include <iostream> using namespace std; int main() { int size; cout << "How many measures are taken? "; cin >> size; int* x; x= new int[size]; for (int i=0; i < size; i++) //glöm inte att sätta värde på i... { cout << "Write temperature for each measure: "; cin >> x[size+i]; //Skrev från början int[size+1] men fungerande inte. ändrade till x. FUNKADE! } for(int i=0; i<size; i++) { cout << "Temperature for measure " << i+1 << " is " << x[size+i] << "\n"; } int sum=0; int mean; for(int i = 0; i < size; i++) { sum = sum+x[size+i]; cout << sum << "\n"; mean = sum/size; } cout << mean; delete[] x; return 0; }

Trädvy Permalänk
Medlem
Registrerad
Apr 2002
Skrivet av gunnar_larsson_mandrake:

Hellu!
Har gjort ett program där användaren bestämmer antalet mätningar som sparas i en array. Användaren får sedan skriva in värdet på varje index. Programmet skriver sedan ut hela listan bara för att visa att det funkar. Inga konstigheter, fungerar som det ska. Jag lägger sedan till en uträkning för medelvärde. Även denna beräkning fungerar. Problemet är bara att kompilatorn/programmet kraschar när det körs klart. Är det något jag gör fel i koden? Kolla i sista if loopen, där medelvärdet görs. Tar man bort denna så kraschar inte programmet. Tack tack för hjälp

#include <iostream> using namespace std; int main() { int size; cout << "How many measures are taken? "; cin >> size; int* x; x= new int[size]; for (int i=0; i < size; i++) //glöm inte att sätta värde på i... { cout << "Write temperature for each measure: "; cin >> x[size+i]; //Skrev från början int[size+1] men fungerande inte. ändrade till x. FUNKADE! } for(int i=0; i<size; i++) { cout << "Temperature for measure " << i+1 << " is " << x[size+i] << "\n"; } int sum=0; int mean; for(int i = 0; i < size; i++) { sum = sum+x[size+i]; cout << sum << "\n"; mean = sum/size; } cout << mean; delete[] x; return 0; }

Fundera över vilka värden size+i kommer anta i den där loopen

Intel i7 6850k || Asus X99-A II || Evga GTX 980Ti || Kingston HyperX Fury 2666 64GB || Samsung 950 Pro 512GB || XB270HU 1440p IPS G-Sync

Trädvy Permalänk
Medlem
Registrerad
Jan 2017

@evil penguin: x[size] i stället? Båda uträkningarna blir rätt, men programmet kraschar fortfarande... :/

Trädvy Permalänk
Medlem
Registrerad
Sep 2012

Om du har en array som heter x (som i din kod), då för att skriva ut första värdet skriver du:
cout << x[0];

När man ska komma åt värden i arrayer så börjar man på index 0, så om du har en array som är 5 lång (tex om du sätter size till 5 i din kod) så kommer första värdet i arrayen att ha index 0, och sista värdet ha index 4.

Så som gunnar_larsson_mandrake skriver, tänk på vilket index du försöker komma åt när du skirver
x[size+i]
eller
x[size]

Trädvy Permalänk
Moderator
Registrerad
Aug 2007

Kan rekommendera dig att köra programmet med en debugger så att du ser på vilken rad det smäller. Det är ovärderligt för felsökning.

Använd gilla för att markera nyttiga inlägg!

Trädvy Permalänk
Medlem
Registrerad
Okt 2013

Fundera på följande rader:
cin >> x[size+i]; //Skrev från början int[size+1] men fungerande inte. ändrade till x. FUNKADE!
cout << "Temperature for measure " << i+1 << " is " << x[size+i] << "\n";
sum = sum+x[size+i];

Tänk på dimensionering av x och vilka index i x som du faktiskt använder i din kod.
Vilket index blir size+i?
Är det inom giltigt värde?

Mao du skriver sönder stacken (där ofta returadressen står) så troligen kraschar det pga det när programmet avslutas.

Eller läs igen vad evil_penguin säger.

Trädvy Permalänk
Medlem
Registrerad
Jan 2017

OK, fixade det nu. Tack för alla förslag! Det som gjorde att det kraschade var att jag delade sum med size. Gick tydligen inte. gjorde ny variabel s=size och använde den istället. Funkar nu perfekt utan att krascha.

Trädvy Permalänk
Medlem
Plats
Göteborg
Registrerad
Feb 2005
Skrivet av gunnar_larsson_mandrake:

OK, fixade det nu. Tack för alla förslag! Det som gjorde att det kraschade var att jag delade sum med size. Gick tydligen inte. gjorde ny variabel s=size och använde den istället. Funkar nu perfekt utan att krascha.

Det borde det fortfarande inte göra om du inte ändrat mer

Som sagt tidigare, prova med en debugger och se vad "size + i" blir.

Trädvy Permalänk
Medlem
Registrerad
Okt 2013

Har du inte fixat din indexing är du ute skriver utanför den minnesadress som du får utnyttja.
Detta ger att du skriver sönder stacken.
I C/C++ (och all övrig) programmering är detta ett jättefel.
När du använder x[] får du inte skriva x[size + i]. För dig skall det stå x[i].
Du behöver inte ett nytt attribut s.

Trädvy Permalänk
Medlem
Registrerad
Jan 2017

Jag la in den sista loopen i den föregående loopen med. Kanske var det också... Här är nya koden som funkar som den ska... Provade att skriva x[i] istället för att skapa ny variabel, men fick det inte att funka tyvärr. Något jag missat?

#include <iostream> using namespace std; int main() { int size; cout << "How many measures are taken? "; cin >> size; float* x; x= new float[size]; for (int i=0; i < size; i++) //glöm inte att sätta värde på i... { cout << "Write temperature for each measure: "; cin >> x[size+i]; //Skrev från början int[size+1] men fungerande inte. ändrade till x. FUNKADE! } float sum=0; float mean; for(int i=0; i<size; i++) { cout << "Temperature for measure " << i+1 << " is " << x[size+i] << "\n"; sum = sum+x[size+i]; //Räknar ut medelvärde. Svår att få rätt iom size. float s = size; //Programmet kraschar om jag delar på size. osäker på varför, men det fungerar om jag skapar en ny variabel med samma värde. mean = sum/s; } cout << "\nMean value is " << mean << "\n"; delete[] x; return 0; }

Trädvy Permalänk
Medlem
Plats
Linköping
Registrerad
Apr 2008
Skrivet av loffis:

När du använder x[] får du inte skriva x[size + i]. För dig skall det stå x[i].

Skrivet av gunnar_larsson_mandrake:

... cin >> x[size+i]; //Skrev från början int[size+1] men fungerande inte. ändrade till x. FUNKADE! ... cout << "Temperature for measure " << i+1 << " is " << x[size+i] << "\n"; sum = sum+x[size+i]; //Räknar ut medelvärde. Svår att få rätt iom size. float s = size; //Programmet kraschar om jag delar på size. osäker på varför, men det fungerar om jag skapar en ny variabel med samma värde. mean = sum/s; ...

Precis som @loffis säger så kan du inte skriva x[size+1], om x har size antal element skall de accessas med x[n], 0 <= n < size, annars kommer du att läsa/skriva på fel plats, vilket kan leda till att du skriver sönder andra variabler eller kraschar, siffran innanför hakparenteserna är alltså en offset från arrayens start. mean = sum / size borde fungera.

Trädvy Permalänk
Medlem
Registrerad
Jan 2017

Bravo! Tack! Det fortsatte faktiskt krascha i ett annat skede haha. Men jag gjorde som ni tippsade och ändrade size till n. Funkar bra nu!!! Tack för alla tips!

Trädvy Permalänk
Medlem
Registrerad
Maj 2014

Om du har size=4 och så har du x[0] x[1] x[2] och x[3] som är giltiga. Lopen börjar och sätter i=0. När du försöker accessa x[size+i] så förösker du alltså accessa x[4] som inte finns.

x[4] läser något annat minne som är efter din array x. Där kan finnas vad som helst. Ännu värre är det om du skriver där.

Jag rekommenderar att om man börjar med programmering bör man lära sig ett annat språk än C/C++. Hade du använt Java eller liknande hade programmet kraschat och skrivit. Index out of bounds exception, 4 vilket innäbär att x[4] är out of bounds eftersom minimum i hakparanteserna är 0 och max är 3.

Trädvy Permalänk
Datavetare
Plats
Stockholm
Registrerad
Jun 2011

Programmet var nog mer ett C-program kompilerat med en C++ kompilator än ett "riktigt" C++ program.

Standard C++ kan absolut upptäcka om man läser utanför allokerat minne, något som då avbryter programmet och upplyser om problemet.

I detta fall skulle den enklast modifieringen vara att använda std::vector<> samt att alltid referera till elementen via metoden at().

#include <iostream> #include <vector> using namespace std; int main() { int size; cout << "How many measures are taken? "; cin >> size; vector<float> x(size); for (int i=0; i < size; i++) //glöm inte att sätta värde på i... { cout << "Write temperature for each measure: "; cin >> x.at(i); //Skrev från början int[size+1] men fungerande //inte. ändrade till x. FUNKADE! } float sum=0; float mean; for(int i=0; i<size; i++) { cout << "Temperature for measure " << i+1 << " is " << x.at(i) << "\n"; sum = sum + x.at(i); //Räknar ut medelvärde. Svår att få rätt iom //size. } mean = sum/size; cout << "\nMean value is " << mean << "\n"; return 0; }

Sitter man på en Skylake/Kaby Lake går det faktiskt att upptäcka minnesproblem även i TS originalprogram! Skylake fick en extension som kallas MPX (Intel Memory Protection Extensions).

Har man en kompilatorn som stödjer detta (vilket aktuella version av GCC och Clang/LLVM gör) så kommer man upptäcka en lång rad vanliga misstag, som att läsa/skriva utanför allokerat minne, användande av en pekare till friat minne m.m.

Så MPX ger nu optimerad C/C++ kod samma check som t.ex. Java/C# explicit gör. Fördelen med C/C++ ihop med MPX är att det är betydligt effektivare.

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer