Zum Inhalt springen

Orffi

Mitglieder
  • Gesamte Inhalte

    252
  • Benutzer seit

  • Letzter Besuch

Alle Inhalte von Orffi

  1. Orffi

    auto_ptr

    Da ISO-C++ keinen Garbage Collector mitbringt, muß der Programmierer dafür sorgen, daß dynamisch reservierter Speicher wieder freigegeben wird. Man wird also zu jedem new ein delete im Quellcode finden. Leider sieht die Welt nicht immer ganz so einfach aus. Ein kleines Beispiel: Man hat eine Funktion, die Speicher dynamisch anfordert und am Ende wieder freigibt. Allerdings wird mitten in der Funktion, also zwischen new und delete, eine Exception ausgelöst. void f (void) { X *obj = new X(); //mache irgendetwas... throw std::exception (); delete obj; } (Am Ende steht der komplette Quelltext, der auch kompilierbar ist.) Bei einem solchen Problem kommt der auto_ptr aus <memory> zum Einsatz. Denn, wie jeder leicht sieht, wird der Speicher nicht freigegeben und man hat ein Speicherloch, denn man hat keine Möglichkeit mehr auf den Speicher zuzugreifen, um ihn wieder freizugeben. Folgender Code hat so ein Speicherloch nicht: void g ( void ) { std::auto_ptr<X> obj ( new X ( "auto" ) ); throw std::exception (); } auto_ptr<> ruft den Destruktor des Objekt, welches er hält, automatisch auf, wenn die auto_ptr Variable den Sichtbarkeitsbereich verläßt. Die Funktion also normal verlassen wird oder durch eine Exception. Da ein auto_ptr nicht besonders schlau ist, kann er keine Referenzen zählen oder sonstwie herausfinden, wer nun auf das Objekt noch zeigt oder nicht. Deswegen passiert etwas sehr interessantes, wenn man einen auto_ptr in einen anderen kopiert. Nach: std::auto_ptr<X> obj2 = obj1; ist obj1 (was auch ein auto_ptr ist) NULL. Kopien von auto_ptr sind also alles andere als gleich!!! Niemals, wirklich niemals sollte man auf die folgende Idee kommen: std::vector<std::auto_ptr<X>> v; sort ( v.begin(), v.end() ); Hier wird intern natürlich hin- und herkopiert, um den Vector zu sortieren. Und bei jeder Kopieraktion ist das Original ein NULL-Pointer! Dies gilt übrigens nicht nur für vector sondern für alle Standard Container. Wie in Funktion i() (siehe unten) zu sehen ist, wird der auto_ptr wie ein ganz normaler Zeiger benutzt. Mit release() gibt der auto_ptr die Verwaltung für das Objekt auf. Man muß sich dann wieder selbst um die freigabe kümmern. Mit reset ('Objekt') kann man dem auto_ptr ein neues Objekt in die Obhut geben. Dabei wird das alte Objekt freigegeben. Hier nun ein komplettes Programm, das vielmehr erklärt als der ganze Text: #include <iostream> #include <memory> #include <string> #include <exception> class X { std::string name; public: X ( std::string ); ~X () { std::cout << "Destruktor Y: " << name << '\n'; } std::string getName () { return name; } }; X::X ( std::string n) : name ( n ) { std::cout << "Konstruktor Y: " << name << '\n'; } void f ( void ) { X *obj = new X ( "normal" ); throw std::exception (); delete obj; } void g ( void ) { std::auto_ptr<X> obj ( new X ( "auto" ) ); throw std::exception (); } void h ( void ) { std::auto_ptr<X> obj1 ( new X ( "obj1" ) ); { std::auto_ptr<X> obj2 = obj1; } std:: cout << "^ Fuer obj1 wurde der Destruktor schon aufgerufen!?!\n"; // weil das Original nach der Kopieraktion auf NULL zeigt. } void i ( void ) { std::auto_ptr<X> obj1 ( new X ( "Horst" ) ); std:: cout << "Name des Objekts: " << obj1 -> getName () << '\n'; obj1.reset ( new X ( "Karl" ) ); X *obj2 = obj1.release(); } int k ( void ) { std::auto_ptr<X> obj1 ( new X ( "Hugo" ) ); X *obj2 = obj1.release(); delete obj2; } int main ( void ) { try { f(); } catch ( std::exception &e ) { std::cout << e.what () << '\n'; } std::cout << "normal wird nicht freigegeben...\n"; try { g(); } catch ( std::exception &e ) { std::cout << e.what () << '\n'; } h (); i (); std::cout << "Karl wird nicht freigegeben...\n"; k (); return 0; } HTH Jan
  2. Ich habe jetzt nicht ganz vor Augen, wie Dein Quelltext aussieht und was Du wann machen willst. Aber Du hast ein TEdit (edtLadeU) Dort sollen Zahlen eingegeben werden, die Du dann mit StrToFloat in eine Fließkommazahl umwandelst. Das schließe ich jetzt einfach mal aus Deiner Exception. Diese Exception wird, wie Du schon richtig bemerkt hast, geworfen wenn ein leerer String in float (StrToFloat gibt long double zurück) umgewandelt werden soll. Aber auch bei "abc" wird natürlich eine Exception geworfen, weil auch "abc" nicht in float umgewandelt werden kann. Wenn Du jetzt eine OnClick-Methode für einen Button hast, die mit der Zahl von edtLadeU Berechnungen durchführen soll, dann kannst Du folgendes tun: if ( Edit1 -> Text == "" ) { Application -> MessageBox ( "Kein Wert in LadeU!", "Fehler", MB_OK ); edtLadeU -> SetFocus (); return; } float LadeU = StrToFloat ( edtLadeU -> Text ); //... Dies prüft wie gesagt nur, ob Du überhaupt etwas eingegeben hast. Oder Du arbeitest komplett mit Exceptions, was ja auch ganz schön ist: float LadeU; try { LadeU = StrToFloat ( Edit1 -> Text ); } catch ( EConvertError &e ) { Application -> MessageBox ( e.Message.c_str(), "Fehler", MB_OK ); edtLadeU -> SetFocus (); return; } //keine Fehler... Berechnung kann durchgeführt werden... HTH Jan
  3. Ein Garabage Collector macht mehr. Wenn ich zwei auto_ptr x und y habe und x=y schreibe, dann ist y danach ein Null-Pointer. Das ist eine sehr, sehr kurze Antwort, ich werde später einen neuen Thread aufmachen und ein wenig dazu schreiben. Jan
  4. Eine kleine Möglichkeit, warum das Programm mit der zweiten Variante gar nicht startet: Du mußt \ Durch \\ ersetzen, da nur \\ einen Backslash erzeugt. HTH Jan
  5. edtLadeU ist also vom Typ TEdit, das solltest Du dazuschreiben. Denn dann ist edtLadeU == "" tatsächlich Unfug. Aber was sicherlich funktioniert ist folgendes: if ( edtLadeU -> Text == "" ) //... if ( edtLadeU == 0 ) ist auch keine tolle Idee (zumindestens in diesem Zusammenhang). Hier wird nur geschaut, ob edtLadeU kein Null-Zeiger ist. Davon darf man ruhig ausgehen, es sei denn, Du hast das TEdit zur Laufzeit erzeugt. HTH Jan
  6. Wie wäre es mit: if ( edtLadeU == "" ) //... HTH Jan
  7. Es gibt folgende Bit-Operatoren: & (und), | (oder), ^ (exclusives oder), ~ (komplementär), << (bitshift nach links), >> (bitshift nach rechts) char byte = ~0; ergibt -1, da alle bits umgedreht werden, aus einer 1 wird eine 0 und aus einer 0 wird eine 1. Da wir uns im 2er Komplementsystem befinden, wird die -1 mit lauter einsen dargestellt. byte = 1; byte <<= 1; alle bits werden um eins nach links verschoben. In diesem Fall nur sichtbar die 1. Aber es werden auch die Nullen verschoben. Die letzte Null fällt hinten raus. Vorne wird eine Null nachgeschoben. Es wird aber immer eine Null nachgeschoben, selbst wenn hinten eine 1 wegfällt. (Das Ergebnis ist byte ==2.) byte1 = 1; byte2 = 2; byte7 = byte1 & byte2; byte == 0, da nur an den Stellen eine 1 gesetzt wird, wo in beiden Variablen eine 1 steht. Also an Stelle x muß in byte1 UND in byte2 eine 1 stehen. Diesen Fall haben wir aber nicht. byte1 = 1; byte2 = 2; byte7 = byte1 | byte2; byte == 3, da eine 1 gesetzt wird wenn an Stelle x in byte1 ODER in byte2 eine 1 steht. byte1 = 1; byte2 = 3; byte = byte1 ^ byte2; byte == 2, da beim XOR eine 1 gesetzt wird, wenn entweder in byte1 oder in byte2 eine 1 steht. Wenn aber an beiden Stellen eine 1 steht, wird eine Null geschrieben. In diesem Fall steht an erster Stelle beides Mal eine 0. HTH Jan
  8. Wenn man sich nicht einig wird, wer den Speicher wieder freigibt, dann kann man ja einen Autopointer (auto_pr) aus <memory> benutzen. Diesen gibt es nur in C++, aber wenn ich das richtig sehe, darf es ja C++-Code sein. Dieser auto_ptr sorgt dafür, daß der Destruktor aufgerufen wird, wenn man keine Referenz mehr darauf hat. Es ist aber bei weitem noch kein Smartpointer (was so etwas wie ein Pointer mit Garbage Collector wäre.) Es fehlt noch eine ganze Menge dazu. Wenn es von Interesse ist, also nicht zu weit vom Thema wegführt, kann ich ein paar Zeilen dazu schreiben. HTH Jan
  9. Natürlich wird LaTeX noch eingesetzt. Es ist nur die Frage wo man schaut. Mir würde es auch nicht im Traum einfallen, einen Brief mit LaTex zuschreiben. Obwohl es sogar vorgefertigte "Klassen" dafür gibt. Aber für wissenschaftliche Arbeiten ist es schon sehr cool. Vor allen Dingen setzt es die Fußnoten dahin, wo sie hingehören. Ich denke aber auch, daß sich für ein LaTex-Forum zu wenig Benutzer finden würden. Hier ein Link zum LaTeX-Kochbuch: http://www.uni-giessen.de/hrz/tex/cookbook/cookbook.html Ansonsten kommt es darauf an, wie abgefahren Deine Frage ist. Ich kann versuchen, Dir zu helfen. Wobei ich ich keine Garantie geben kann, daß ich tatsächlich hilfreich bin. Wenn uns jetzt ein Admin verrät, welches Forum das beste wäre, könnten wir es versuchen. Jan
  10. Die Länge des Arrays bekommst Du über folgenden Ausdruck: int lenArray = sizeof ( myArray ) / sizeof ( char* ); Natürlich kannst Du in myArray[0] nur Strings speichern die maximal so lang sind wie "text2". Ähnlich verhält es sich mit den anderen beiden Einträgen im Array. "Echte" Strings bekommst Du in C++ mit der Klasse string. Allerdings kennt C keine Strings, da mußt Du Dir mit new helfen, um dynamisch Texte speichern zu können. HTH Jan
  11. Orffi

    Blinkende Schrift

    Windows zum Beispiel ist ein Multitasking Betriebssystem. Das bedeutet, daß mehrere Programme "gleichzeitig" laufen können. Jedes Programm ist ein Prozeß. Da man normalerweise aber nur einen Prozessor zur Verfügung hat, kann nur ein Prozeß die Ressource Prozessor benutzen. Unter Multitasking Betriebssystemen findet also ständig ein Wechsel der Prozesse statt. Das hat weitreichende Konsequenzen, weil zum Beispiel die Register der CPU und der Gleichen mehr gesichert werden müssen, damit man sie später, wenn der Prozeß wieder CPU-Zeit bekommt, wieder zur Verfügung hat und die Situation die Gleiche ist wie vor der Unterbrechung. Ein Thread ist der "kleine Bruder" eines Prozesses, er wird deswegen auch leichter Prozeß genannt. Ein Thread gehört immer zu genau einem Prozeß aber ein Prozeß kann mehrere Threads haben. Hier ist das Probem ähnlich. Hier müssen auch ein paar Daten gesichert werden, bevor innerhalb des Prozesses ein anderer Thread zum Zuge kommt. Allerdings ist ein Threadwechsel schneller, da nicht so viele Daten gesichert werden müssen. Aber es kostet halt Zeit. HTH Jan PS: Oh, da seid ihr ja alle schneller als ich gewesen... @Woodstock: Das tut mir leid, ich hatte jetzt gar nicht auf der Rechnung, daß die Beiträge auch Threads sind. Die meinte ich aber nicht.
  12. Orffi

    Blinkende Schrift

    "Und sorry wenn ich nicht weiß ob es in C/C++ so einen 'Befehl' gibt." Was soll das denn? Habe ich irgendetwas dazu gesagt, daß man irgendetwas wissen müßte? Ich glaube es ist normal wenn man etwas nicht weiß. Ich habe mit dem ersten Posting nur erklären wollen, daß man Header-Dateien nicht einfach austauschen kann. Mit meinem zweiten Posting wollte ich Dich keineswegs angreifen und habe dies auch gleich in den ersten Satz hineingeschrieben. Ein Threadwechsel ist auch nicht kostenlos, er kostet Zeit und das bedeutet, daß Deine Suche noch länger dauert. Das meinte ich mit verschwenden. Wenn Du Dich angegriffen fühst, dann tut es mir leid, ich kann nur nochmal sagen, daß dies nicht meine Absicht war. Jan
  13. Orffi

    Blinkende Schrift

    Ich habe keine Ahnung worum es in diesem Programm geht, deswegen bitte das Folgende nicht als Angriff ansehen. Vielleicht geht es ja nicht anders. Wenn ich mich aber 4 Minuten in einer Schleife (ich habe es jetzt so verstanden, daß Du etwas suchst), dann würde ich meine CPU-Zeit nicht damit "verschwenden", eine Schrift zum Blinken zu bringen. Ich würde vielmehr schauen, ob es nicht Möglichkeiten gibt, die Suche zu beschleunigen. Persönlich finde ich es schon ein wenig heftig einen Thread zu starten, um Text zum Blinken zu bringen. Vielmehr würde ich schauen, ob ich nicht einen Interrupt finde, den man dafür benutzen könnte. Will meinen: Ich würde mich in eine Interruptbehandlung einklinken. Jan
  14. Ich weiß nicht so recht, was Du mit "Das Editfeld soll genauso funzen wie die Combobox. Blos ohne den Pfeil und das Aufpopen halt." sagen möchtest. Auch bin ich mir nicht so sicher was Du mit Klassen meinst. Ich nehme aber auch an, daß Du Komponenten meinst. Hier ist noch ein Link zu einer Komponentenseite: http://www.torry.net/index.htm Vielleicht findest Du dort was Du suchst. HTH Jan
  15. Ich persönlich finde Bruce Eckel sehr gut. Hier kannst Du "Thinking In C++" herunterladen: http://www.mindview.net/Books/DownloadSites Allerdings ist das Buch in Englisch geschrieben und ein bißchen Kenntnis in C wäre auch nicht schlecht. Ein Blick ist es aber alle mal wert. HTH Jan
  16. Keine Sorge, ich werde nicht schießen. Ich möchte nur darauf hinweisen, daß ich in meinem Ursprungsposting erwähnt habe, daß es auch Systeme geben mag, die nur void main (void) anbieten. Es ist ja nichts so, daß ich von einem anderen Stern komme und nicht weiß daß es Gründe für void main (void) gibt. Ich wollte nur, daß sich jeder bewußt ist, wann er standardkonform ist und wann nicht. Es mag (gute) Gründe geben, warum man sich nicht an den Standard hält, aber diese Entscheidung sollte meiner Meinung ganz bewußt getroffen werden. Jan
  17. Orffi

    Blinkende Schrift

    conio.h gehört nicht zum Standard und deswegen kocht da jeder Hersteller sein eigenes Süppchen. (Da kann man mal sehen, wie nützlich es ist einen Standard zu haben. Oder man ärgert sich jetzt darüber, daß der Standard keine schönen Textausgaben vorgesehen hat.) Natürlich kann man die Header-Dateien nicht austauchen. Denn in Header-Dateien stehen ja (fast) nur Deklarationen und keine Definitionen der Klassen und/oder Funktionen. Ich persönlich würde ja auf das Blinken verzichten... Jan
  18. Ich nehme an, Du hast in der Hilfe nachgeschaut, oder? Wenn nicht, dann mach' es doch einfach. Aber ich glaube nicht, daß man alles auf einmal einlesen/auslesen kann. Aber das macht (fast) nichts, denn Borland stellt alles zur Verfügung was man braucht. Zum Schreiben in eine Datei: Laß einfach eine for-Schleife von 0 bis Count-1 (zu finden unter TListItems) laufen. In der Liest Du von das Array von Item aus und schreibst sie in eine Datei. Zum Lesen denkst Du Dir irgendein sinnvolles Format aus und liest bis zum Dateiende alle Daten ein und fügst sie, wie oben beschrieben, in TListView ein. HTH Jan
  19. Nee, der Median wird nicht eingesetzt. Der einfachste Quicksort hat auch gar nichts mit Mittelwerten zu tun. Quicksort nimmt sich das Element (z.B.) aus der Mitte und fängt an, alle Elemente, die kleiner als dieses Element sind, nach links zu sortieren und die größeren Elemente nach rechts. Worst case bedeutet im ungünstigsten Fall, daß heißt wenn die zu sortierenden Daten in einer ungünstigen Reihenfolge vorliegen. Für Quicksort würde der worst case so aussehen: Die Liste mit der Länge n wird in eine Liste der Länge n-1 und 1 aufgeteilt. Die Liste mit n-1 Elementen wird dann in n-2 Elemente und 1 aufgeteilt usw. Daraus ergibt sich dann das n². Wie die Daten dann vorliegen müssen, wenn ich das Element immer aus der Mitte der zu sortierenden Liste auswähle, um den worst case zu erreichen, kannst Du Dir ja mal spaßigerweise überlegen. HTH Jan
  20. Naja, schau doch einfach in der Hilfe nach. Mehr kann ich auch nicht tun. Ich habe kurz geschaut und im ersten Moment habe ich kein SaveToFile / LoadFromFile gefunden. Ich benutze zwar kein BCB5 aber ich glaube nicht, daß Borland es dort eingeführt hat. Bei TListBox geht LoadFromFile ja über die Eigenschaft Items, was vom TStrings ist. TStrings bringt LoadFromFile mit. Aber bei TListView sind Items nicht vom Typ TStrings. Ich fürchte Du mußt Dir selber eine Load-/Save-Funktion schreiben. HTH Jan
  21. Beide Algorithmen arbeiten nach dem "teile und herrsche"-Prinzip. Das bedeutet, man teilt ein Problem in zwei kleinere Probleme auf und hofft, daß das kleinere Problem lösbar ist. Wenn dem nicht so ist, dann verkleinert man das Problem weiter. Aus der Beschreibung sieht man schon, daß man die beiden Probleme ganz gut rekrusiv implementieren kann. (Muß man aber nicht, wenn man will kann man die Rekursion auflösen.) Es gibt auch ein paar unterschiede, die jeweils den einen oder anderen Algorithmus bevorzugen. Mergesort sortiert Teillisten. Um das zu bewerkstelligen teilt Mergesort die Listen solange auf (halbiert sie), bis die Liste nur noch aus einem Element besteht. Jetzt kann man die Listen sortieren und fügt sie nun wieder zusammen. Am Ende hat man eine sortierte Liste. Quicksort funktioniert ein wenig anders: Hier nimmt man sich ein Element (x) aus der Liste und sortiert alle Elemente die kleiner als x sind nach links und die Elemente, die größer sind, nach rechts. Das wird dann rekursiv für die ganze Liste gemacht. Dieses x sollte man natürlich einigermaßen schlau wählen... Am Ende bekommt man auch hier die sortierte Liste heraus. Beide Algorithmen besitzen im average case die Komplexität n*log n. Wobei n die Anzahl der Elemente sind. Im ungünstigsten Fall (worst case) hat Quicksort allerdings die Komplexität n². HTH Jan
  22. Also ob Java zum lernen wirklich schöner, als C++ ist, will ich so nicht unterschreiben. Es ist auch eine Geschmacksfrage. Aber in Java gibt es auch haufenweise Zeiger nur sind die im System "versteckt" und wenn man nicht aufpaßt macht das Programm auch nicht das, was man sich vorgestellt hat. Das gemeine speziell an C ist, daß ein Programm ohne Fehler kompiliert aber trotzdem abstürzen kann. In Java werden zur Kompilierzeit eine Menge Fehler aufgedeckt. C/C++ ist maschinennäher und wenn man sich einmal durch die beiden durchgearbeitet hat, dann sind sie auch nicht mehr so wild. Jan
  23. Ich weiß nicht, ob es das ist, was Du suchst aber: Du schnappst Dir erstmal eine Zeigervariable vom Typ TListItem. TListItem *newline; Nun soll es auf eine neue Zeile im TListView zeigen, also: newline = myListView -> Items -> Add (); Und als letztes füllst Du die neue Zeile mit Inhalt: newline -> Caption = "Hallo" newline -> SubItems -> Add ( "Welt!" ); // Weitere unterkategorien... HTH Jan
  24. Der C++ Builder bringt schon die Komponente TListView mit. Mit der kannst Du mehrzeilige Listenfelder erzeugen. Zu finden ist die Komponente unter der Kategorie Win32. HTH Jan
  25. Was Klotzkopf schreibt ist ganz, ganz wichtig! Am Ende eines char Arrays wird noch '\0' angehängt. Wenn man dafür keinen Speicherplatz reserviert kann alles passieren. Es kann sein, daß das Programm funktioniert, es kann sein, daß das Programm bei ersten Aufruf abstürzt oder es kann irgendwann abstürzen. Im Allgemeinen ist so ein Problem unter Umständen sehr häßlich zu debuggen. Ansonsten geht Klotzkopf bei seiner Lösung durch die Liste und gibt jedes einzelne Element frei, wobei er sich den Zeiger auf das nächste Element merkt, damit er dann dieses Element frei geben kann und so weiter und so fort... HTH Jan

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...