Could someone please do me a favour and compile this stuff on his system, then try to run it and give me the console output?
Sortierverfahren.cpp line 23 does something I have never seen happen before, when I try to run the program - and I have not the slightest idea as to what could cause this.
Apparently I somehow broke that STL container. Or my OS. Or my PC. ~~
And I would like to know which one of these three.
Compiled with "g++ -Wall -Wextra -o Test *.cpp".
... Oh, of course, if you see my fault, feel free to tell me about it - I am at the end of my wisdom.
LordZsar1
09-05-2010 08:08 PM
Solved. Turned out that copy-constructors of parent classes tend not to work in a defined way when invoked from children...
That does not mean that my code works now - cout seems to be a greater menace than anyone cared to tell me. ~~
LordZsar1
09-05-2010 09:48 PM
It's out to get me, that is the sole explanation! But I can do something it has not planned for, I can suprise it, ha, and I will suprise it: by exposing it to the world!
If anyone feels like having a little bit of unused time and grand need for a headache, mayhap he can take a look at this and tell me, where exactly I... how is it said... "fucked up".
Code:
#ifndef HEADER_ItemSet
#define HEADER_ItemSet
#include <string>
#include <vector>
using namespace std;
class ItemSet : vector<string>
{
protected:
ItemSet(ItemSet * vorhandeneMenge); // übernimmt die Konfiguration des Parameters
// ererbte Funktionen - was muss man tun, um einfach die Elternversion nutzen zu können!?
vector<string>::iterator begin();
vector<string>::iterator end();
// echte Funktionalität
// setzt this->sollSortiertBleiben
void bleibeSortiert (bool sortiertBleiben);
// fügt Element ein und beachtet this->sollSortiertBleiben
void fuegeEin (string gegenstand);
// setzt this->sortierfunktion
void nimmSortierfunktion(void (*sortierfunktion)(vector<string> * const));
// sortiert Elemente mit übergebener Funktion
void sortiere (void (*sortierfunktion)(vector<string> * const));
// Unsinn, den die Aufgabe fordert
void push_back(string gegenstand);
void sort ();
string back ();
unsigned int matches (ItemSet andereMenge, unsigned int bisHier);
bool contains (ItemSet andereMenge);
ItemSet * subset (unsigned int i);
};
// gibt die Elemente in vorliegender Reihenfolge in den Ausgabestrom ein
ostream & operator<<(ostream & ausgabe, ItemSet & menge);
class ItemSetContainer : vector<ItemSet>
{
public:
ItemSetContainer();
// ererbte Funktionen - was muss man tun, um einfach die Elternversion nutzen zu können!?
vector<ItemSet>::iterator begin();
vector<ItemSet>::iterator end();
class Sortierverfahren
{
protected:
static void quickSort_sortieren(vector<string> * const liste, unsigned int links, unsigned int rechts);
static unsigned int quickSort_teilen (vector<string> * const liste, unsigned int links, unsigned int rechts);
ItemSet::~ItemSet()
{
delete(&(this->istSortiert)); // Keine Ahnung, ob man das überhaupt tun muss...
delete(&(this->sollSortiertBleiben)); // aber wir tun es mal lieber.
this->vector<string>::~vector(); // An dieser Stelle könnte theoretisch auch destroy(this) stehen,
// aber wären die Aufrufe äquivalent?
// Wenn nicht - welcher ist dann der richtige?
}
// sollte aus Symmetriegründen ItemSet * nehmen, aber leider...
unsigned int ItemSet::matches(ItemSet andereMenge, unsigned int bisHier)
{
vector<string>::iterator itA = this->begin();
vector<string>::iterator itB = andereMenge.begin();
unsigned int position = 0;
bool stimmenUeberein = true;
if(itA == this->end() ^ itB == andereMenge.end()) // Einer von beiden ist am Ende, der andere nicht.
{
stimmenUeberein = false;
}
else if(stimmenUeberein && itA == this->end() && itB == andereMenge.end())
{
position = bisHier; // bisHier wird zurückgegeben, wenn beide übereinstimmen - auch wenn
// mangels ausreichender Länge gar nicht bis dorthin gezählt wurde
}
}
while(stimmenUeberein && position < bisHier);
return position; // Ist das Ergebnis kleiner als bisHier, dann zeigt es das erste Vorkommen eines Unterschiedes.
}
if(this->size() < andereMenge.size()) // Das Enthaltende soll kleiner als das Enthaltene sein.
{
return false;
}
else
{
vector<string>::iterator itA = this->begin();
vector<string>::iterator itB = andereMenge.begin();
if(this->size() == andereMenge.size()) // Beide sind gleich groß - ergo müssen sie identisch sein.
{
do
{
if(*itA != *itB)
{
return false;
}
itA++;
itB++;
}
while(itA != this->end());
return true;
}
else // Die Elemente von andereMenge müssen sich in der Reihenfolge
// ihres Auftretens zwischen den Elementen von this verbergen.
{
do
{
while(itA != this->end() && *itA != *itB)
{
itA++; // Wir zählen durch die Elemente von this und vergleichen sie mit einem aus andereMenge.
}
if(itA == this->end() && (*itA != *itB)) // Wir sind am Ende, haben aber ein Element
// aus andereMenge nicht gefunden.
{
return false;
}
else
{
itB++; // Sobald dieses Element gefunden wurde, betrachten wir das nächste.
}
}
while(itB != andereMenge.end()); // Alle Elemente von andereMenge wurden gefunden.
return true;
}
}
}
ItemSet * ItemSet::subset(unsigned int i)
{
ItemSet * untermenge = new ItemSet(this);
if(i < this->size())
{
untermenge->erase(untermenge->begin() + i); // Dadurch sollten wir die Referenz auf die Kopie
// von *(this->begin() + i) verlieren... oder?
}
do
{
getline(eingabestrom, neueZeile); // Funktion aus der Strings-Bibliothek - ist eleganter als ifstream->getline
if(!neueZeile.empty())
{
char * t;
char * zeile = new char[neueZeile.size() + 1]; // aus algorithmischer Sicht überflüssig...
ItemSet * neueMenge = new ItemSet(false, &Sortierverfahren::bubbleSort); // ItemSet neueMenge erzeugt CTD
// nach Ende der if-Struktur...
// keine Ahnung wie, ist aber so.
if(eingabestrom.eof())
{
neueZeile.push_back(' '); // um sicherzugehen, dass der letzte Rest auch gefunden wird
}
strcpy(zeile, neueZeile.c_str()); // uneleganter Weg, const char * zu char * zu wandeln...
// Nun zerhacken wir unsere Zeile in bester Massenmödermanier in handliche Stückchen.
// Eigentlich könnten wir das auch direkt mit neueZeile tun, aber leider scheint
// es kein C++-Äquivalent zu dieser C-Funktion zu geben.
t = strtok(zeile, " ");
while(t != NULL)
{
neueMenge->push_back(string(t));
// cout << t << " ";
t = strtok(NULL, " ");
// cout << (t != NULL) << " "; // Hier kommen wir nie an, wenn wir als vierte Zeile
// "konrad zuse heinz billing heinz nixdorf" eintragen:
// Nach konrad ist dann Schluss. Keine Ahnung, warum.
}
// cout << endl;
this->push_back(*neueMenge); // funktioniert aus unerfindlichen Gründen
// nicht für Mengen mit identischen Inhalten
// Muss man die Referenzen (t, zeile) jetzt mit delete(void *) bereinigen... oder nicht?
}
}
while(!eingabestrom.eof());
eingabestrom.close();
// Die Destruktoren von eingabestrom und neueZeile werden jetzt automatisch aufgerufen...
// oder wir haben uns verlesen und sie werden es nicht. Was wäre zu tun?
}
unsigned int Sortierverfahren::quickSort_teilen(vector<string> * const liste, unsigned int links,
unsigned int rechts)
{
unsigned int i = links;
unsigned int j = rechts;
// cout << liste->back() << endl; // Hier hatten wir einen ganz, ganz seltsamen Fehler, den wir uns
// nicht ganz erklären können. Deshalb benutzen wir bubbleSort.
// Lag womöglich am operator<< und ist bereits behoben.
string pivotelement = liste->back();
// cout << "Pivotelement: " << pivotelement << endl; // Bis hierher sind wir nie gekommen...
The whole thing compiles under Windows and with minimal changes under Linux, but while it works "somewhat" under the former, it does not even do a little under the latter.
Two Sheds
28-05-2010 04:05 AM
not sure if you are still looking at this, but one problem that I see is that in ItemSet::~ItemSet() you are deleting some things you shouldn't be. You only delete things you new.
I'm not that familiar with c/c++ anymore, haven't used it regularly for a long time, if you are still looking at this I can take a longer look...