Miért nem olvassa be rendesen a stringet? (C++)
a feladat szövege:
Beolvas egy pozitív számot, majd dinamikusan lefoglal egy tömböt, ennyi Csapat struktúra számára.
Minden csapatnak van egy csapatneve, egy létszáma és tárolja a csapattagok neveit is.
Kérje be a csapatok adatait! A létszám megadása után dinamikusan foglaljon helyet a tagok nevei számára!(Nem minden csapat azonos létszámú)
Az első csapat nevének bekérésénél összeomlik a program valamiért. Próbáltam getline-al is, úgy meg átugorja a lépést bekérés nélkül.
#include <iostream>
#include <string>
using namespace std;
struct csapat {
string csapatnev;
int letszam=1;
string* nevek = new string[letszam];
};
int main()
{
int meret;
cout << "Adja meg a csapatok szamat:\n";
cin >> meret;
csapat* csapatok = new csapat[meret];
cout << "Csapatok adatai:\n";
for (int i = 0; i < meret; i++) {
cout << i + 1 << ". csapat neve:\n"; cin>> csapatok[i].csapatnev;
cout << i + 1 << ". csapat letszama:\n"; cin >> csapatok[i].letszam;
for (int j = 0; j < csapatok[i].letszam; j++) {
cout << j + 1 << ". jatekos neve:"; cin >> csapatok[i].nevek[j];
}
}
delete[] csapatok;
}
Súlyos memóriakezelési hiba van a programodban.
Ami történik: létrehozol egy meret elemszámú tömböt, ami dinamikus. Eddig jó LENNE!
Csakhogy ha osztályt,struktúrát,akármit létrehozol, lefut egy konstruktor. Most neked olyan nincs, így default fut.
Azaz beállít mindent 0-ra (vagy memóriaszemétre, a c++ memóriakezelése már régen került a fejembe).
A struct-ban van egy létszám=1, ennek értéke 1 lesz, és lefoglal egy letszam méretű string tömböt utána, AMI PONTOSAN 1 ELEMŰ!!!.
Ezt utána a mainben hiába írod át 5-re, vagy akármennyire, attól a string tömb mérete nem változik meg!
Második hiba: oké, hogy törlöd a csapatokat, de nincs destruktorod. Ez azt fogja jelenteni, hogy a MEMÓRIÁBAN MARAD a letszam méretű string tömböd, mert senki nem törli ki azt onnan!
Ezeket javítsd ki!
Elsőre lehetséges megoldás, hogy a struct-ban nem hozod létre new-val a tömböt, csak üresen hagyod a pointert, és miután beolvastad, mekkora lesz, de még mielőtt használnád, azelőtt foglalod neki a memóriát.
destruktor problémára meg ezt ajánlom: vagy írj egy destruktor függvényt a structba, ami végigmegy for-ral a nevek tömbön, és delete[i], vagy ugyanezt csinálod a mainben a delete[] csapatok ELŐTT!
uhh, köszi szépen, már erre keresem a megoldást vagy 2 órája.
Kijavítottam és működik is elvileg, bár 2 helyen a beolvasásnál aláhúzza nekem hasonló "warning"-al: "C6385 Reading invalid data from 'csapatok': the readable size is '(unsigned int)*36+4' bytes, but '72' bytes may be read."
#include <iostream>
#include <string>
using namespace std;
struct csapat {
string csapatnev;
int letszam;
string* nevek;
};
int main()
{
int meret;
cout << "Adja meg a csapatok szamat:\n";
cin >> meret;
csapat* csapatok = new csapat[meret];
cout << "Csapatok adatai:\n";
for (int i = 0; i < meret; i++) {
cout << i + 1 << ". csapat neve:\n"; cin>> csapatok[i].csapatnev;
cout << i + 1 << ". csapat letszama:\n"; cin >> csapatok[i].letszam;
csapatok[i].nevek = new string[csapatok[i].letszam];
for (int j = 0; j < csapatok[i].letszam; j++) {
cout << j + 1 << ". jatekos neve:"; cin >> csapatok[i].nevek[j];
}
}
for (int i = 0; i < meret; i++) {
delete[] csapatok[i].nevek;
}
delete[] csapatok;
}
Nálam Wall szinten is két warningot ad csak, de azok inicializálatlan változók:
a csapat struct-ban a letszam legyen = 0 alapból, ahol 1 volt, és a nevek legyen null, akkor biztos nem lehet warning. De lényegtelen, mert jól kezeled utána a kódban, amit a fordító nem feltételez, szóval nyugodtan hagyhatod így is.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!