Błędne wczytywanie danych z pliku binarnego.

0

Witam,

Mam do oddania projekt na uczelni, jak myślałem cały jest ukończony - jednak, gdy ustawiłem statyczne wczytywanie bibliotek oraz skompilowałem w trybie Release pojawił się błąd. Mianowicie, na samym początku programu mam coś a'la system logowania, gdzie z pliku binarnego wczytuję login oraz hasło. Gdy odpalam w trybie Debug - wszystko działa poprawnie. Gdy odpalam w trybie Release - nie mogę się poprawnie zalogować. Poniżej wklejam kod, który wczytuje dane z pliku:

        ifstream ifs("file/admin.foo", ios::binary);


	char* temp = new char[sizeof(Admin)];
	ifs.read(temp, sizeof(Admin));
	Admin* data = (Admin*)(temp);

Zostaje wczytane coś takiego: 'đ'

Czy ktoś z Was może zn przyczynę takiego zachowania?
Może ktoś ma inny sposób aby skompilować program w taki sposób, aby na innych komputerach działał z pliku *.exe ?

Pozdrawiam

0

Co to jest Admin (co ma w środku)?
Tak się nie zapisuje klas, a już na pewno tak się nie zapisuje danych logowania.

0

Dobra rada przy okazji - nigdy nie podawaj względnych ścieżek, bo w końcu się na tym przejedziesz. Zawsze podawaj bezwzględne.

0
MarekR22 napisał(a):

Co to jest Admin (co ma w środku)?
Tak się nie zapisuje klas, a już na pewno tak się nie zapisuje danych logowania.

Admin {
string login;
string password;

public:
Admin(const string login, const string paszowe)
: login(login), password(password) {}
} ;

2

String to klasa, a nie typ prosty. A skoro klasa, to znaczy, że zapisuje Ci do pliku adres obiektu, a nie jego zawartość. Jak chcesz tak automatycznie zapisać stringa, to musisz mieć go w postaci tablicy znaków o określonej długości.

0

Obsługa plików binarnych jest bardziej zaawansowana, proste rzutowania zazwyczaj prowadzą do błędów. 1) można to robić przy typach prostych 2) trzeba uwzględnić różnego rodzaju wyrównania ect. Zanim napisze się obsługę pliku binarnego, to trzeba określić jak ma on w środku wyglądać. Zaczynanie od prostych zrzutów pamięci, to proszenie się o kłopoty.

0

swoją drogą ciekawe, co ten rozmiar klasy zwrócił - mój konik to C, a nie C++, więc może dla kogoś to oczywiste, ale na moje chłopskie oko, to string jest klasą. Rozmiar stringa jest dynamiczny, więc tutaj jest pewnie tylko rozmiar pointera, czyli 4 lub 8 bajtów. Albo w sumie nie - pewnie rozmiar też obiektów w środku. Tak czy siak, na pewno to nie jest rozmiar stringa... A te klasy zawarte w stringu, pewnie też mają jakieś inne klasy w sobie, może po czymś dziedziczą.. O kurw, chłopie :D Ale żeś zamarzył, że to będzie działać :D Użyj lepiej zwykłej struktury i tablic znaków w środku

0

Zazwyczaj środowisko tworzy sobie osobne katalogi dla Debug i Release.
Czy w katalogu z releasem masz ?

file/admin.foo

Zgodnie ze standardem otwierając program, otrzymujesz path aktualnego katalogu.
Jak otwierasz plik, za pomocą IDE?

0

koszt alokowania danych na stercie jest dość spory, dlatego współczesne optymalizacje std::string działają troszkę inaczej.
Wykorzystuje się Short String Optimization (SSO):
sizeof(std::string) obecnie zwraca dużo więcej niż wielkość wskaźnika (zależnie od kompilatora) i zawartość małych napisów nie jest trzymana na stercie, ale bezpośrednio wewnątrz klasy string.

Jaki to może mieć skutek? Że takie naiwne zapisywanie danych prosto do pliku, dla krótkich napisów zadziała, a dla długich już nie.
Ba nawet zmiana tryby budowania, może zmienić granicę, przy której SSO już działa.

Wniosek pokazany kod działał nie dlatego, że było dobrze, ale przez zwykły łut szczęścia (a raczej pech).
Takie dane należy zapisywać pisząc właściwą implementację iternalizacji i ekstrenalizacji.

1 użytkowników online, w tym zalogowanych: 0, gości: 1