Du bist nicht eingeloggt.

Login

Pass

Registrieren

Community
Szene & News
Locations
Impressum

Forum / Bits und Bytes

C++ ruft nach Hilfe :D

  -1- -2- -3- vorwärts >>>  
uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 31.12.2007 um 15:14 Uhr
Zuletzt editiert am: 31.12.2007 um 15:14 Uhr

Ein weitereres Mal komme ich in C++ nicht weiter :D
folgendes:

Ich habe einen Pointer Objekts der auf ein Array zeigt.
Jedes dieser Arrayelemente zeigt auf jeweils ein Objekt.

Zitat:


(Objekts+0)->Pointer->Objekt0
(Objekts+1)->Pointer->Objekt1
(Objekts+2)->Pointer->Objekt2
usw...


Nun will ich mit einer Funktion eins dieser Objekte löschen...

Das ganze sah bisher so bei mir aus:

Zitat:


void killObjekt(char pName[20])
{
for (int i=0; i<Objektcount; i++)
{
if ((*(Objekts+i))->compareNames(pName))
{
Objekt *Kill=*(Objekts+i);
Objekt **Temp=new Objekt* [Objektcount--];
int j=0;
for (int k=0; k<(Objektcount+1); k++)
{
if (*(Objekts+k)==Kill)
{
j=1;
}
else
{
*(Temp+(k-j))=*(Objekts+k);
}
}
Objekts=new Objekt* [Objektcount];
for (j=0; j<Objektcount; j++)
{
*(Objekts+j)=*(Temp+j);
}
delete []Temp;
delete Kill;
GUI->Objektscroller->Items->Delete(GUI->Objektscroller->Items->IndexOf(GUI->Objektscroller->Text));
GUI->Objektscroller->Text="Neues Objekt anlegen";
GUI->edName->Text="";
GUI->edX->Text="";
GUI->edY->Text="";
GUI->edVx->Text="";
GUI->edVy->Text="";
GUI->edMass->Text="";
break;
}
}
}

(leider zeigt T-U nicht mehr als ein Leerzeichen an, hoffe der Quelltext ist halbwegs übersichtlich)

Problem:
Erstelle ich 2 Objekte gibt es kein Problem.
Bei 3 oder mehr Objekten gibt es häufig (nicht immer) errors beim löschen der Objekts
(Befehl: delete []Objekts;)

Ich bdanke mich wieder mal bei jedem der sich dieser Sache annimmt und wünsche natürlich allen, die das lesen einen schönen Silvesterabend

UT3 Sucks ^^

xMATADORx - 39
Experte (offline)

Dabei seit 02.2005
1115 Beiträge

Geschrieben am: 31.12.2007 um 16:12 Uhr

...bist du nicht aufm TG in Ehingen?

Zuerst den ersten Eintrag lesen!!! Linkshänder an die Macht!!!

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 31.12.2007 um 16:31 Uhr

Zitat von xMATADORx:

...bist du nicht aufm TG in Ehingen?

Das is vollkommen richtig, aber es tut nix zur Sache
PS:Ich weiß auch das man so was da jetz noch nich lernt, aber ich brauchs trotzdem

UT3 Sucks ^^

MrSandy - 32
Experte (offline)

Dabei seit 07.2007
1526 Beiträge

Geschrieben am: 31.12.2007 um 17:19 Uhr

http://www.rafb.net/paste/

!!
Polaris
Experte (offline)

Dabei seit 07.2006
1766 Beiträge
Geschrieben am: 31.12.2007 um 17:40 Uhr
Zuletzt editiert am: 31.12.2007 um 17:42 Uhr

Bevor ich ausführlich Antwort geben kann, wären ein paar Erläuterungen zu dem Code nicht schlecht, denn der sieht sehr konfus und unlogisch teilweise aus ...

kleine Zusatzfragen:
Was bedeutet löschen bei dir?
Das eine Objekt vom Speicher entfernen und einfach an der Stelle ein neues Objekt anlegen??
(btw. Wenn du C++ verwendest, warum nimmst du nicht std::string, sondern ein char-Array?)

Patriotismus ist die Tugend der Bosheit! (Oscar Wilde)

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 31.12.2007 um 18:00 Uhr

Zitat von Polaris:

Bevor ich ausführlich Antwort geben kann, wären ein paar Erläuterungen zu dem Code nicht schlecht, denn der sieht sehr konfus und unlogisch teilweise aus ...

kleine Zusatzfragen:
Was bedeutet löschen bei dir?
Das eine Objekt vom Speicher entfernen und einfach an der Stelle ein neues Objekt anlegen??
(btw. Wenn du C++ verwendest, warum nimmst du nicht std::string, sondern ein char-Array?)

a)Dieses Objekt aus dem Speicher löschen
b)Mach ich einfach, hab noch nix anderes gelernt ^^
Du sprichst warscheinlich vom Datentype string, diesen habe ich auch schon benutzt, aber ich nehm jetz halt char :D

UT3 Sucks ^^

Polaris
Experte (offline)

Dabei seit 07.2006
1766 Beiträge
Geschrieben am: 31.12.2007 um 18:10 Uhr
Zuletzt editiert am: 31.12.2007 um 18:36 Uhr

Also ausführliche Antwort.
Mir sind ein paar Dinge an deinem Code aufgefallen:

1. Du mischst bei der direkten Verwalten den Zugriff mittels Pointern auf die Objekte (iteratoren) und mittels Indizes - das führt zu einem ziemlich undurchsichtigen Code.
2. Anstatt (*(objekts + i)) würde ich an deiner stelle immer objekts[i] schreiben, das erhöht die lesbarkeit doch deutlich und führt zu einer Vermeidung vieler unnötiger Klammern.


Direkt nachvollziehen kann ich den Code jetzt leider nicht, dazu fehlt mir gerade schlicht die Zeit bei dem Wirrwarr ...
for (int k=0; k< (Objektcount+1); k++) {
//...
}
Objekts=new Objekt* [Objektcount];
/* !!! !hier erzeugst du ein Speicherleck, weil der alte Speicher von Objekts nie freigegeben wird !!!!*/
for (j=0; j<Objektcount; j++) {
//...
}


ich habe aber mal ein Snippet kurz gemacht, dass den von dir gewünschten Zweck erfüllen sollte - das kannst du dir in Ruhe anschauen und dann versuchen von selber deine Fehler zu finden.

void killObjekt(std::string pName) {
bool ObjektKilled = false;
for(unsigned i = 0; i < Objektcount && !ObjektKilled; ++i) {
if(Objekts[i]->getName() == pName) {
Objekt ** Temp = new Objekt * [Objektcount - 1];
for(unsigned j=0; j < Objektcount-1; ++j) {
if(j < i)
Temp[j] = Objekts[j];
else
Temp[j] = Objekts[j+1];
}
delete Objekts[i];
Objekts = Temp;
GUI->Objektscroller->Items->Delete(GUI->Objektscroller->Items->IndexOf(GUI->Objektscroller->Text));
GUI->Objektscroller->Text="Neues Objekt anlegen";
GUI->edName->Text="";
GUI->edX->Text="";
GUI->edY->Text="";
GUI->edVx->Text="";
GUI->edVy->Text="";
GUI->edMass->Text="";
ObjektKilled = true;
}
}
}

Also ich hoffe ich habe keine Fehler reingemacht, bin auch gerade nicht mehr ganz da.
Und ich bete dafür, dass der Zuweisungsoperator von Objekt von dir korrekt überladen ist, denn sonst wirst du ziemlich schnell ziemlich viele Speicherlecks und undefiniertes Verhalten haben.

//Edit:
Fehler ausgebessert *schäm*

Patriotismus ist die Tugend der Bosheit! (Oscar Wilde)

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 31.12.2007 um 18:15 Uhr
Zuletzt editiert am: 31.12.2007 um 18:18 Uhr

Zitat von Polaris:

Also ausführliche Antwort.
Mir sind ein paar Dinge an deinem Code aufgefallen:

1. Du mischst bei der direkten Verwalten den Zugriff mittels Pointern auf die Objekte (iteratoren) und mittels Indizes - das führt zu einem ziemlich undurchsichtigen Code.
2. Anstatt (*(objekts + i)) würde ich an deiner stelle immer objekts[i] schreiben, das erhöht die lesbarkeit doch deutlich und führt zu einer Vermeidung vieler unnötiger Klammern.


Direkt nachvollziehen kann ich den Code jetzt leider nicht, dazu fehlt mir gerade schlicht die Zeit bei dem Wirrwarr ...
for (int k=0; k< (Objektcount+1); k++) {
//...
}
Objekts=new Objekt* [Objektcount];
/* !!! !hier erzeugst du ein Speicherleck, weil der alte Speicher von Objekts nie freigegeben wird !!!!*/
for (j=0; j<Objektcount; j++) {
//...
}


ich habe aber mal ein Snippet kurz gemacht, dass den von dir gewünschten Zweck erfüllen sollte - das kannst du dir in Ruhe anschauen und dann versuchen von selber deine Fehler zu finden.

void killObjekt(std::string pName) {
bool ObjektKilled = false;
for(unsigned i = 0; i < Objektcount && !ObjektKilled; ++i) {
if(Objekts[i]->getName() == pName) {
// kannst natürlich auch mit char-array und deiner Comparefunktion arbeiten
Objekt ** Temp = new Objekt * [Objektcount - 1];
for(unsigned j=0; j < Objektcount-1; ++j) {
if(j < i)
Temp[j] = Objekts[j];
else
Temp[j] = Objekts[j+1];
}
for(unsigned j = 0; j < Objektcount; ++j)
{ delete Objekts[i]; }
delete [] Objekts;
Objekts = Temp;
GUI->Objektscroller->Items->Delete(GUI->Objektscroller->Items->IndexOf(GUI->Objektscroller->Text));
GUI->Objektscroller->Text="Neues Objekt anlegen";
GUI->edName->Text="";
GUI->edX->Text="";
GUI->edY->Text="";
GUI->edVx->Text="";
GUI->edVy->Text="";
GUI->edMass->Text="";
ObjektKilled = true;
}
}
}

Also ich hoffe ich habe keine Fehler reingemacht, bin auch gerade nicht mehr ganz da.
Und ich bete dafür, dass der Zuweisungsoperator von Objekt von dir korrekt überladen ist, denn sonst wirst du ziemlich schnell ziemlich viele Speicherlecks und undefiniertes Verhalten haben.

Folgendes:
Ich lege mir ein Array an Pointen zu, diese Pointer zeigen auf Objekte
Ich will den entsprechenden Pointer im Array und das entsprechende Objekt löschen...
Dabei will ich nicht (wie du es gemacht hast) die Objekte duplizieren, sondern nur die Pointer des Array duplizieren und den Pointer sowie dessen Objekt, bei denen der Name passt, löschen...

UT3 Sucks ^^

Polaris
Experte (offline)

Dabei seit 07.2006
1766 Beiträge
Geschrieben am: 31.12.2007 um 18:30 Uhr
Zuletzt editiert am: 02.01.2008 um 15:42 Uhr

hmm ich kopiere hier auch nur Zeiger, meine deletes waren z.T. falsch:

void killObjekt(std::string pName) {
bool ObjektKilled = false;
for(unsigned i = 0; i < Objektcount && !ObjektKilled; ++i) {
if(Objekts[i]->getName() == pName) {
Objekt ** Temp = new Objekt * [Objektcount - 1];
for(unsigned j=0; j < Objektcount-1; ++j) {
if(j < i)
Temp[j] = Objekts[j];
else
Temp[j] = Objekts[j+1];
}
delete Objekts[i];
delete [] Objekts; // bin aber gerade unsicher, ob das delete so stimmt, ich check's morgen noch mal nach, wenn ich mehr Zeit habe
Objekts = Temp;
GUI->Objektscroller->Items->Delete(GUI->Objektscroller->Items->IndexOf(GUI->Objektscroller->Text));
GUI->Objektscroller->Text="Neues Objekt anlegen";
GUI->edName->Text="";
GUI->edX->Text="";
GUI->edY->Text="";
GUI->edVx->Text="";
GUI->edVy->Text="";
GUI->edMass->Text="";
ObjektKilled = true;
}
}
}

/Edit:
Also wenn gewärleistet, dass der Zeiger in "Objekts" dessen Objekt gelöscht worden ist, immer auch auf ein Objekt zeigt, welches korrekt mit new auf dem FreeMemory angefordert wurde, dann dürfte das so stimmen.

Allerdings gibt mir die Funktion schon zu denken.
Wei du hier anhand einer Zeichenkette die du übergibst (wer ruft die Funktion eigentlich auf? - kennt der Aufrufer nicht den Index?) hier die Entscheidung triffst ein Objekt zu löschen, sieht mir nach einem möglicherweise nicht ganz so eleganten Design aus.
Planst du hier eine Verwaltung von einem Array aus Pointern? - dann: warum das Rad neu erfinden? Wozu gibt's die Sequenzcontainer der STL:
std::vector<Objekt *>
std::deque<Objekt *>
std::list<Objekt *>

Patriotismus ist die Tugend der Bosheit! (Oscar Wilde)

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 02.01.2008 um 14:37 Uhr
Zuletzt editiert am: 02.01.2008 um 15:38 Uhr

Langsam stinkts mir...

Jetz scheitert mein Programm an der selbst gebastelten compareNames-Funktion...

So sieht der Spaß zum löschen JETZT aus...

Zitat:


void Control::killObjekt(char pName[20])
{
Objekt **Temp=new Objekt*[Objektcount--];
int j=0;
for (int i=0; i<(Objektcount+1); i++)
{
if (Objekts[i]->compareNames(pName))
{
j=-1;
delete Objekts[i];
}
else
{
*(Temp+(i+j))=*(Objekts+i);
}
delete (Objekts+i);
}
Objekts=Temp;
GUI->Objektscroller->Items->Delete(GUI->Objektscroller->Items->IndexOf(GUI->Objektscroller->Text));
}

Der Witz ist, dass auch die Funktion zum erstellen eines neuen Objekts bei der compareNames-Funktion scheitert...
Und damit ihr das ganze inspizieren könnt poste ich hier mal noch die Funktion compareNames

Zitat:


bool Objekt::compareNames(char pName[20])
{
for (unsigned int i=0; i<StrLen(pName); i++)
{
if (pName[i]!=Name[i])
{
return false;
}
}
return true;
}


Ich verstehs langsam echt nicht mehr, davor lief die Funktion einwandfrei genauso wie sie da steht...

Danke an alle die mir helfen


UT3 Sucks ^^

Polaris
Experte (offline)

Dabei seit 07.2006
1766 Beiträge
Geschrieben am: 02.01.2008 um 16:11 Uhr
Zuletzt editiert am: 02.01.2008 um 16:12 Uhr

also im Parameter kannst du dir die 20 sparen, hier wird ein Zeiger kopiert ...
ich würde "const char * pName" als Parameter vorziehen ...
Ist dein String korrekt nullterminiert?


(btw - auch hier gibt es aus C die vorgefertigte Funktion strcmp(const char *, const char*))

Patriotismus ist die Tugend der Bosheit! (Oscar Wilde)

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 02.01.2008 um 16:33 Uhr
Zuletzt editiert am: 02.01.2008 um 16:35 Uhr

mit strcmp gibt es bei meiner Funktion gar keine Treffer mehr...

Um dir zu sagen wie meine Strings entstehen:

Die Info liegt in
a) einem Editfeld beim erstellen (Ansistring)
b) in einer Combobox ebenfalls als Ansistring
beide Ansistrings werden durch funktion c_str()
also String.c_str() umgewandelt...

Ich melde mich später wieder, jetz grad hab ich anderes zu tun =)

UT3 Sucks ^^

Polaris
Experte (offline)

Dabei seit 07.2006
1766 Beiträge
Geschrieben am: 02.01.2008 um 16:40 Uhr
Zuletzt editiert am: 02.01.2008 um 16:41 Uhr

Zitat von uwebaier:

mit strcmp gibt es bei meiner Funktion gar keine Treffer mehr...

Um dir zu sagen wie meine Strings entstehen:

Die Info liegt in
a) einem Editfeld beim erstellen (Ansistring)
b) in einer Combobox ebenfalls als Ansistring
beide Ansistrings werden durch funktion c_str()
also String.c_str() umgewandelt...

Ich melde mich später wieder, jetz grad hab ich anderes zu tun =)

auch noch mit VCL ^^
also das .c_str() sollte schon korrekt sein, aber: woher willst du wissen, dass sich dein Benutzer auf 19 Zeichen bei der Eingabe beschränkt?
arbeite doch mit const char * - dann kannst du mittels strlen aus der C Library die Länge ermitteln und dann vergleichen - mit statischer Länge zu arbeiten ist sicher keine gute Idee.
btw. strcmp liefert 0 zurück für 2 gleiche strings

Patriotismus ist die Tugend der Bosheit! (Oscar Wilde)

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 02.01.2008 um 17:22 Uhr

Ich bin halt Newbie, also lass mich doch :D

Problem ist jetzt nicht mehr die Funktion sondern das aufrufen der Funktion :D

Ich glaub das Problem is tiefergehend, ich werd mich mal rumprobieren
Am liebsten würd ich dir einfach das ganze Programm geben, aber das will ich dir nicht zumuten ^^

UT3 Sucks ^^

bassmaster - 48
Profi (offline)

Dabei seit 10.2004
631 Beiträge

Geschrieben am: 02.01.2008 um 22:09 Uhr

also wie polaris schon geschrieben hat, solltest du versuchen das rad nicht neu zu erfinden. in jeder framework gibt es listen und so wie es aussieht, versuchst du eine verkettete liste nachzuprogrammieren, die leider nicht objektorientiert ist. das bedeutet, dass du sie nichtmal wiederverwenden kannst.

nimm hier wirklich fertige klassen. die gibts in der stl, mfc, atl oder was auch immer. sie laufen zuverlässig und du brauchst keine angst haben, dass dir der speicher wegläuft.

verwende strcmp anstatt deines comparenames.

verwende in untermethoden immer ein const, wenn du den zeiger nicht änderst!

verwende verwaltete stringklassen anstatt die veralteten chararrays. das wird dir viel ärger ersparen.

ich hoffe du hast das programmieren nicht in der schule gelernt, sonst würde ich gern mal mit deinem lehrer reden wollen.

http://www.impala64.de/blog - http://www.impala64.de/ - www.myspace.com/impala64lowrider

uwebaier - 36
Halbprofi (offline)

Dabei seit 06.2005
124 Beiträge

Geschrieben am: 02.01.2008 um 22:48 Uhr

Du würdest warscheinlich lachen, aber ich hab iregndwie das Gefühl das Mein Lehrer mit so was heillos Überfordert wäre...

Was genau meinst du mit fertigen Klassen? Für Datentypen usw. oder wie?

Und noch eins: (ersten) Fehler beim Löschen gefunden:
Jedes Objekt hat einen Namen, aber irgendwie scheint es als ob der Name eines Objekts einfach mit "" Überschrieben wird... (Ihr wisst was ich meine xD)

Danek für den Rat, ich such mir mal was was ich als neuen Texttyp nehmen kann


UT3 Sucks ^^

  -1- -2- -3- vorwärts >>>
 

Forum / Bits und Bytes

(c) 1999 - 2026 team-ulm.de - all rights reserved - hosted by ibTEC Team-Ulm

- Presse - Blog - Historie - Partner - Nutzungsbedingungen - Datenschutzerklärung - Jugendschutz -