• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

std::bad_alloc przy zapisie/odczycie vectora do pliku binarnego

VPS Starter Arubacloud
0 głosów
181 wizyt
pytanie zadane 23 marca 2020 w C i C++ przez Quanti994 Początkujący (340 p.)
   loadStudentFile.read((char*)&student.ratings,sizeof(float));
 studentFileSave.write((char*)&ratings[0],ratings.size()*sizeof(float));

Wyskakuje mi błąd std::bad_alloc w momencie zapisu/odczytu pliku binarnego z kontenerem vector

Nie wiem czy dobrze zapisuje/odczytuje kontener vector do pliku binarnego 

komentarz 23 marca 2020 przez adrian17 Ekspert (349,240 p.)
Um... możesz pokazać jakie są typy tego student, ratings? Ogólnie definicje typów?

Ale na oko, to nie ma prawa działać - tylko muszę widzieć typy, żeby wyjaśnić dlaczego ;)
komentarz 23 marca 2020 przez Quanti994 Początkujący (340 p.)
student jest typu Student - struktury danych ucznia

ratings to kontener vector typu float (znajduje sie w strukturze Student) przechowujący oceny ucznia

kod całości jest spory bo to aplikacja konsolowa dziennika uczniów z ocenami (mój projekt w celu utrwalenia materiału)

2 odpowiedzi

0 głosów
odpowiedź 23 marca 2020 przez adrian17 Ekspert (349,240 p.)
edycja 23 marca 2020 przez adrian17

Zakładam że deklaracja wygląda mniej więcej tak:

struct Student {
    std::vector<float> ratings;
};
studentFileSave.write((char*)&ratings[0],ratings.size()*sizeof(float));

To na upartego jeszcze zrobi to co chcesz, ale tutaj:

loadStudentFile.read((char*)&student.ratings,sizeof(float));

std::vector to nie jest tablica. vector to obiekt opakowujący wskaźnik na dynamicznie zaalokowaną tablicę. Ta powyższa linia próbuje nadpisać zawartość obiektu std::vector kilkoma bajtami (które reprezentują floaty), co nie ma sensu, bo tak naprawdę nadpisujesz bebechy vectora, a nie tablicę. Trzeba pisać do tablicy.

Jeśli uprzednio będziesz znał rozmiar vectora i zrobisz coś takiego:

student.ratings.resize(rozmiar);
loadStudentFile.read((char*)&student.ratings[0],student.ratings.size()*sizeof(float));

To to prawdopodobnie zadziała, ale... ogólnie taki sposób serializacji przez pisanie/czytanie innych typów jak bajty i zapisywanie do pliku jest niezalecane i prędzej czy później się na Tobie zemści.

komentarz 23 marca 2020 przez Quanti994 Początkujący (340 p.)
Jaki zatem sposób serializacji polecasz ?
komentarz 23 marca 2020 przez adrian17 Ekspert (349,240 p.)

To jest... ciężki temat. https://isocpp.org/wiki/faq/serialization

Można zawsze serializować do tekstu i mieć ustalony jakiś super prosty format tekstowy (podobny do takich, jakie używają na SPOJu).

Natomiast, na dłuższą metę, "porządne" rozwiązanie to "użyj gotową bibliotekę" - a jaką konkretnie, zależy od zastosowań. Jest boost::serialization i różne konkurencyjne formaty binarne (msgpack, protobuf etc), jest JSON (i też kolejne tuziny konkurencyjnych bibliotek do JSONa) etc.

Albo, jeśli tak naprawdę chcesz używać pliku jako bazę danych studentów, to... lepiej użyć prawdziwą bazę danych :P Albo lokalnie sqlite który daje Ci prosty plik, albo zdalny serwer postgresa/mysqla/etc.

Oczywiście, nie sugeruję że którekolwiek z rozwiązań jest proste dla osoby dopiero uczącej się C++a :/ Więc przynajmniej przez jakiś czas można zostać przy formatach "ręcznych tekstowych lub binarnych i w międzyczasie oswajać się z językiem.

komentarz 24 marca 2020 przez j23 Mędrzec (195,220 p.)

@adrian17, ogólnie taki sposób serializacji przez pisanie/czytanie innych typów jak bajty i zapisywanie do pliku jest niezalecane i prędzej czy później się na Tobie zemści.

Bez przesady. Pewne rzeczy nie nadają się do zapisu tekstowego i trzeba je zapisywać w sposób binarny. Trzeba wiedzieć, co się robi i zwracać uwagę na wielkość typów.

0 głosów
odpowiedź 23 marca 2020 przez Quanti994 Początkujący (340 p.)
edycja 24 marca 2020 przez Quanti994
Program działa!

Przy zapisywaniu vektora do pliku trzeba pamiętać o zmiennej w strukturze ucznia,przechowującej wielkość wektora (np. liczbe ocen) i w momencie dodania nowego ucznia ją wyzerować.

Podobne pytania

0 głosów
1 odpowiedź 752 wizyt
0 głosów
1 odpowiedź 371 wizyt
pytanie zadane 16 marca 2020 w C i C++ przez Quanti994 Początkujący (340 p.)
0 głosów
1 odpowiedź 1,758 wizyt
pytanie zadane 6 lutego 2019 w C i C++ przez kamasazi98 Początkujący (410 p.)

92,957 zapytań

141,916 odpowiedzi

321,148 komentarzy

62,287 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...