C++; Program fungerar men kraschar

Permalänk

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; }

Permalänk
Medlem
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

Visa signatur

Desktop: Ryzen 5800X3D || MSI X570S Edge Max Wifi || Sapphire Pulse RX 7900 XTX || Gskill Trident Z 3600 64GB || Kingston KC3000 2TB || Samsung 970 EVO Plus 2TB || Samsung 960 Pro 1TB || Fractal Torrent || Asus PG42UQ 4K OLED
Proxmox server: Ryzen 5900X || Asrock Rack X570D4I-2T || Kingston 64GB ECC || WD Red SN700 1TB || Blandning av WD Red / Seagate Ironwolf för lagring || Fractal Node 304

Permalänk

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

Permalänk

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]

Permalänk
Hedersmedlem

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.

Visa signatur

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

Permalänk
Medlem

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.

Permalänk

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.

Permalänk
Medlem
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.

Permalänk
Medlem

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.

Permalänk

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; }

Permalänk
Medlem
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.

Permalänk

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!

Permalänk

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.

Permalänk
Datavetare

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.

Visa signatur

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