Seite 1 von 1

[gelöst] frage: QList::removeAt() funktioniert nicht sicher?

Verfasst: 24. November 2007 17:59
von slash-ex
Mir ist aufgefallen, dass bei manchen Löschversuchen der Inhalt der Liste noch vorhanden ist und nicht korrekt gelöscht wurde. Ich bin etwas verwirrt. Hat sonst noch jemand so ein Problem?

Ich denke es muss an der Implementierung liegen. Bisher half bei mir nur ein Umkopieren in eine andere Liste und ein vollständiges clear() der alten.

Allerdings frage ich mich natürlich ob so etwas grundlegendes tatsächlich nicht funktionieren kann, andererseits funktioniert bisher alles andere, dh. zugriffe ziemlich gut. und wenns nicht an der removeAt funktion liegen würde, dann würde ich nach dem umkopieren in eine andere Liste auch ne Fehlfunktion bekommen... ich frage mich ob ich eine Bug-Meldung machen sollte.

Außerdem spiele ich mit dem gedanken die QList durch eine eigene verkettete Liste zu ersetzen... um letzte Zweifel aus dem Weg zu räumen.

Verfasst: 24. November 2007 20:04
von upsala
Ich behaupte jetzt einfach mal, daß der Fehler in deinem Code und nicht bei Qt zu suchen ist...

Verfasst: 25. November 2007 01:45
von slash-ex
ok, ich habe mir eine eigene liste geschrieben (vielleicht brauch die ja einer mal irgendwann... aber der fehler ist immer noch vorhanden ):


Code: Alles auswählen

#include <iostream>

namespace dtl
{

template <class T>
class vector
{
private:
	T *data;

public:
	//! eigentlich priv
	int index;
	vector *next;
	vector *prev;

	//!konstruktor
	vector();
	vector(T &v);
	vector(vector &v);
	~vector();

	//! setter
	bool append(T data);
	//! cleaner
	void removeAt(int i);
	void clear();
	//! getter
	T get_last();
	T get_first();
	T at(int index);

	int size();
}; 

//! konstrukoren & destruktoren
template <class T>
vector<T>::vector() {
	next = NULL;
	prev = NULL;

	index = 0;
	data = new T;
}

template <class T>
vector<T>::~vector()
{

}

//! daten-settups
template <class T>
bool vector<T>::append(T data) {
	vector *new_node = new vector;
	*new_node->data = data;
	new_node->next = NULL;

	//verknüpfung zum alten beim neuen element
	new_node->prev = this->next;

	//verknüpfung zum neuen beim alten element
	this->next = new_node;

	new_node->index = index;
	index++;
}

//! getter
template <class T>
int vector<T>::size()
{
	return index;
}

template <class T>
T vector<T>::get_last()
{
	if(next->data != NULL)
		return *next->data;
}

template <class T>
T vector<T>::get_first()
{
	vector *old_pointer = next;

	while(true) {
		if(next->index == 0) {
			T data;
			if(next->data != NULL)
				data = *next->data;
			next = old_pointer;
			return data;
		}
		else {
			next = next->prev;
		}
	}
}

//! getter
template <class T>
T vector<T>::at(int ind)
{
	vector *old_pointer = next;

	if(ind > index-1)
		return *next->data;
	if(ind < 0)
		return at(0);

	while(true) {
		if(next->index == ind) {
			T data;
			if(next->data != NULL)
				data = *next->data;
			next = old_pointer;
			return data;
		}
		else {
			next = next->prev;
		}
	}
}

//! cleaner
template <class T>
void vector<T>::clear()
{
	vector *old_pointer = next;

	for(int i = 0; i < index; i++) {
		old_pointer = next;
		next = next->prev;

		delete old_pointer;
	}
}

template <class T>
void vector<T>::removeAt(int ind)
{
	vector<T> *temp = new vector<T>;
	T buffer[index];

	for(int i = index-1; i >= 0; i--) {
		T data = *next->data;
		buffer[i] = data;
		next = next->prev;
	}
	for(int i = 0; i < index; i++) {
		if(i != ind) {
			temp->append(buffer[i]);
		}
	}
	next = temp->next;
}

}

Verfasst: 25. November 2007 12:56
von flossi
Hallo,
slash-ex hat geschrieben:ok, ich habe mir eine eigene liste geschrieben (vielleicht brauch die ja einer mal irgendwann... aber der fehler ist immer noch vorhanden ):
Mir sind zwei Dinge nicht klar:
a) Warum benutzt man eine Liste, wenn man eine removeAt(index) Funktion benötigt? Ist eine vector nicht sinnvoller? (Du nennst Deine Listenimplementierung ja auch vector ;) )
b) Warum schreibt man eine Liste, wenn doch die STL alles mögliche bietet und Qt selbst auch noch eine Teilmenge hiervon bereitstellt?

Schöne Grüße,
Sven

Verfasst: 25. November 2007 13:41
von slash-ex
ich wollte herausfinden wo der fehler herkommt, darum habe ich ne eigene löschfunktion implementiert...
außerdem habe ich davor noch nie ne liste geschrieben und wollte es mal schnell probieren.

das problem schien zu sein, dass ich removeAt nicht in einer schleife aufrufen kann, da sich mit jdem aufruf die größe der liste ändert und so alles durcheinanderrutscht.

Verfasst: 25. November 2007 14:53
von flossi
slash-ex hat geschrieben:das problem schien zu sein, dass ich removeAt nicht in einer schleife aufrufen kann, da sich mit jdem aufruf die größe der liste ändert und so alles durcheinanderrutscht.
Das ist ein häufig anszutreffendes Problem. Eine mögliche Lösung wäre den Iterator, den erase() zurückliefert zu benutzen:

Code: Alles auswählen

QList<Item>::iterator it = list.begin()
while( it != list.end() )
{
  // Tu was
  if ( soll gelöscht werden )
    it = list.erase(it)
  else
    ++it
}
Schöne Grüße,
Sven

Verfasst: 25. November 2007 15:47
von slash-ex
danke