Różne wyniki (Visual Studio oraz Ideone)

0

Dostałem zadanie napisania listy dwukierunkowej obiektowo. Co do samego zadania nie mam pytań, jednak podczas jego realizacji otrzymuje dziwne wyniki używając środowiska Microsoft Visual Studio 2015 community. Poniżej przedstawiam kod:

#include <iostream>
//#include <conio.h>
#include <string>
using namespace std;

class ListElement {
	int key;
	ListElement* next;
	ListElement* prev;
	friend class List;

public:
	ListElement* Element(int key);
	int getKey();
	ListElement(int k);
};

class List {
	ListElement* firstElement;
	int size;

	friend class ListElement;

public:
	void addToBeginning(int key);
	void addToEnd(int key);
	ListElement* getElement(int key);
	bool contains(int key);
	void remove(int key);
	void clearAll();
	void printList();
};

int main() {
	List* list = new List();
	list->addToEnd(3);
	list->addToEnd(5);
	return 0;
}

//konstruktory

ListElement::ListElement(int k) {
	this->key = k;
	this->next = NULL;
	this->prev = NULL;
}

void List::addToEnd(int key) {
	if (this->firstElement) {
		ListElement element(key);
		ListElement *tmp = this->firstElement;
		cout << tmp << endl;
		cout << tmp->key << endl;
		cout << tmp->next << endl;
	}
	else {
		ListElement element(key);
		this->firstElement = &element;
		cout << this->firstElement << endl;
		cout << this->firstElement->key << endl;
		cout << this->firstElement->next << endl;
	}
} 

Powyższy kod ma dodać na koniec listy 3 oraz wypisać: adres tego elementu, klucz elementu (czyli liczbe 3) oraz adres następnego elementu, po czym wstawiając liczbę 5 odnieść się ponownie do pierwszego elementu i zrobić dokładnie to samo.

Wyniki z konsoli (używając VS):

001BF640
3
00000000

001BF640
-858993460
CCCCCCCC

Wyniki z ideone.com:

 0xbfc8a930
3
0
0xbfc8a930
3
0

Wartości z ideone są wartościami oczekiwanymi... Mógłby ktoś mi pomóc i wyjaśnić, dlaczego wyjścia nie są takie same?

0

patrząc do końca, co niby robi void List::addToEnd(int key)? Bo na pewno nie to na co wskazuje nazwa, bo np tworzy ListElement na stosie a nie na stercie, nie modyfikuje firstElement jeśli firstElement ma już ustawioną jaką wartość.
Już po tym: dziwne, że się crashem nie kończy.

0

addToEnd powinno dodać element na koniec listy. Warunkiem if sprawdzam czy mamy głowę listy. Jeżeli jej nie ma to powołuje nowy obiekt ListElement z określonym kluczem (3) a następnie ustawiam firstElement na adres utworzonego obiektu. W przeciwnym przypadku (jeżeli głowa istnieje) to teoretycznie powinno się uzyskać dostęp do ostatniego elementu listy używając jakieść pętli. Wiem że ta funkcja tego nie robi, bo zatrzymałem się w trakcie jej tworzenia. Proszę nie patrzeć na treść zadania, tylko na sam kod (czy jest on poprawnie napisany). Moim celem było utworzenie obiektu z wartością pola key = 5 a następnie utworzenie wskaźnika, który wskazywałby na pierwszy element listy. Dlaczego tmp daje poprawną wartość (adres pierwszego elementu), a tmp->key oraz tmp-> next już nie? Dlaczego na ideone udało mi się uzyskać to co chciałem a w VIsualu nie?

1
ListElement element(key);
this->firstElement = &element;

Wynosisz poza funkcję wskaźnik do lokalnie utworzonego obiektu na stosie. Po wywołaniu kolejnej funkcji ramka stosu (w tym twój obiekt) zostanie zastąpiona innymi danymi.
Poczytaj więcej o zarządzaniu pamięcią w C++.

1

to było pytanie retoryczne!
Udowadniam ci, że jest źle, to że nie masz crasha to szczęście (a raczej pech).
ListElement powinien być tworzony operatorem new i niszczony operatorem delete, a u ciebie tego nie ma.
Nie odróżniasz sterty od stosu, ergo za wcześnie dla ciebie na pisanie listy.

1

Wewnątrz tego addToEnd tworzysz element na stosie, a nie na stercie i zostaje on usunięty zaraz po wyjściu z funkcji, przez co masz tam dangling pointer.

0

Dziękuję za odpowiedź

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