Wskazówka bądź pomoc w odnalezieniu błędu. C++

0

Witam wszystkich forumowiczów !
Jestem nowy w społeczności i mam problem z moim projektem zaliczeniowym z przedmiotu Języki i Paradygmaty Programowania.

W załączniku przesyłam cały plik programu z VS 2013 oczywiście okrojony z folderów Debug, Release i innych zbędnych rzeczy.

Po kilku długich chwilach spędzonych nad tym projektem doszedłem do wniosku, iż sam sobie nie poradzę. Stąd więc ogromna prośba do was o sugestie bądź propozycję naprawy problemu który opiszę poniżej.

Ogólne działanie programu jest takie iż ma on operując na klasach przetrzymywać dane wierzchołka a dokładnie: nazwę, numer, i dwie współrzędne. Dodatkowymi z wielu funkcjonalności są zapis i odczyt z pliku binarnego. I tu zaczyna się problem, a mianowicie program zapisuje dane do pliku bin natomiast przy odczycie jest troszeczkę gorzej.

Pod debuggerem wykryłem problem w tym miejscu:

strm.read(reinterpret_cast<char*>(ob), size);

A polega on na tym iż zmienna do której zapisuje dane odczytane z pliku inicjuje się poprzez konstruktor poprawnie lecz po z rzutowaniu do char * i zapisaniu w zmiennej powstaje błąd "Error reading characters of string". Zapewne jest to mój karygodny błąd lecz nie jestem w stanie go zlokalizować.

Jeśli coś źle umieściłem lub pomyliłem działy to przepraszam i proszę o wyrozumiałość...
Proszę o pomoc z góry dziękuję !

0

Jakiego typu jest ten obiekt ob? Czy on jest blokiem pamięci tak jak twierdzisz że jest rzutując na char*?

0

Obiekt "ob" jest typu T. T natomiast jest tablicą elementów node.

0

Wklej deklarację typu node. Ale prawie w ciemno mogę stwierdzić, że tablica elementów node to nie jest coś, co można traktować jako tablicę char.

0
 
class mcoord
{
protected:
	double *crd;						//Dynamicznie alokowana tablica współrzędnych
public:
	my_mess error;						//Zmienna typu my_mess umożliwiająca obsługę błędów
	mcoord(double xx, double yy);		//Konstruktor sparametryzowany
	mcoord();							//Konstruktor domyślny
	~mcoord();							//Destruktor zwalnia pamięć
};
class node : public mcoord
{
	int numb;			//Numer wierzchołka
	char str[2];		//Nazwa wierzchołka
public:
	node(int nb, char *st, double xx, double yy);				//Konstruktor sparametryzowany
	node(node const &right);									//Konstruktor z parametrem o typie node
	node();														//Konstruktor domyślny
	node &operator = (const node &right);						//Przeciążenie operatora =
	bool operator == (const node &right);						//Przeciążenie operatora == dla parametru o typie node
	bool operator == (const int &right);						//Przeciążenie operatora == dla parametru o typie int
	friend ostream & operator << (ostream &out, node &ob);		//Przeciążenie operatora << aby umożliwić wyświetlanie danych typu T na monitorze
	friend istream & operator >> (istream &in, node &ob);		//Przeciążenie operatora >> aby umożliwić wczytanie danych typu T z klawiatury
}; 
0

No to tablica tych node na pewno nie może być traktowana jako tablica char. Skąd w ogóle pomysł takiego rzutowania?

Edit: Ok skłamałem. Nie doczytałem, że to jest plik binarny.

0

Ogólnie akurat ta linijka jak całe przeciążenie operatora <<< i >> zostało podane przez profesora na uczelni. Skąd pomysł na rzutowanie zapewne stąd że wymaga tego specyfikacja metody read().

0

No to nie przejdzie. Musisz przeczytać kolejne elementy w pliku i przypisać je do odpowiednich obiektów.

0

Może wkleję całą funkcję:
To przeciążenie operatora >>:

template <class T>
fstream & operator >> (fstream &strm, T *ob)
{
																					//SF ta metoda nie wywoluje sie
	streamsize size = static_cast<streamsize>(sizeof(T));
	strm.read(reinterpret_cast<char*>(ob), size);

	if ((strm.bad() || strm.fail()) && !strm.eof())
	{
		my_mess error;
		system("CLS");
		error.mess(ERR_OPEN_FILE);
	}
	return strm;
}

A tu wywołanie:

void my_interface::load_object()
{
	data_bin.open("dane.bin", ios::in | ios::binary);
	vector.clear_all();
	data_bin.seekg(0);

	while (data_bin.good())
	{
		node *tmp;
		tmp = new node;
		data_bin >> &tmp;
		if (*tmp == node(0, " ", 0, 0)) break;
		vector.push(*tmp);
		delete tmp;
	}

	data_bin.close();

	system("CLS");
	cout << "Dane zostaly poprawnie wczytane z pliku...\n\n";
}

Tylko jest mały problem bo ta linijka jest od profesora i nie wiem czy on błąd zrobił ale sądząc po jego doświadczeniu to wątpię. :)

0

Ta linijka też jest profesora?

data_bin >> &tmp;

tmp już jest wskaźnikiem, po co brać adres tego wskaźnika?

0

To moja linijka...
Teraz to widzę tylko mam jeszcze jedno pytanie a mianowicie teraz kiedy odczytuję dane z pliku to dwie pierwsze zmienne odczytują się poprawnie a dwie pozostałe czyli współrzędne nie wczytują się poprawnie.

1

Problemem jest to, że w klasie masz wskaźniki double *crd! Wskaźników nie zapisuje się do i nie odczytuje z pliku, bo to prowadzi do uszkodzenia heap-a (crash segfault).

0

xxD :)
Właśnie jeszcze wczoraj zauważyłem ten problem bo jak ustawiłem komentarz na destruktor klasy mcoord i nie wyłączyłem programu tylko od razu wczytałem dane to wszystko było ok.
Tylko klasa mcoord razem z zapisem i odczytem jest kodem od profesora raczej nie podlega zmianie. Czyli co mam mu powiedzieć bo będę musiał do niego iść na konsultacje ?

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