memcpy, memmove, calloc, memset in C++?
-
Dravere schrieb:
...Es kommt manchmal vor, dass man einen Speicherbereich mit 0s füllen möchte...
Wann passiert das ? Und warum ?
Ich muss gestehen, dass bei mir so schnell nicht das Bedürfnis aufkommt, "einen Speicherberich mit Nullen zu füllen"...
Ich kenne zwar aus C das Bestreben, einen "Objekte" zu initialisieren, aber dafür hat man in C++ Konstruktoren, die das viel besser erledigen.
Ansonsten lösen "genullte Speicherbereiche" keine besonderen Glücksgefühle in mir aus.
Gruß,
Simon2.
-
In C++ benutzt man zB eher std::vector oder std::tr1::array, anstelle sich um die Speicherverwaltung zu kümmern.
Der grosse Nachteil von C++ ist aber, das die "c++ Schnittstellen" nicht standartiesiert sind. Sprich, willst du Programme mit anderen Modulen erweitern und dich nicht auf einen compiler (eine programmiersprache) festlegen, laesst dich C++ gnadenlos im Stich

Da werden Schnittstellen incompatibel zueinander zum Teil nur durch blosse compiler-parameter.Das wiederum heisst, bei modularer programmierung bist du auf C-Schnittstellen angeweisen.
Das wiederum heisst, willst du da einigermassen performant bleiben (ueberfluessige kopien vermeiden) musst du das Spiel in C mitspielen.
Ansonsten stimme ich zu, innerhalb geschlossener Programme sollt man in C++ den Biblos die speicherverwaltung ueberlassen, und nur notfalls mittels eigener Allokatoren da eingreifen.
Ciao ...
-
RHBaum schrieb:
...
Der grosse Nachteil von C++ ist aber, das die "c++ Schnittstellen" nicht standartiesiert sind. Sprich, willst du Programme mit anderen Modulen erweitern und dich nicht auf einen compiler (eine programmiersprache) festlegen, laesst dich C++ gnadenlos im Stich
Da werden Schnittstellen incompatibel zueinander zum Teil nur durch blosse compiler-parameter. ...Naja - aber nur, wenn man auf Link- oder Laufzeitebene ansetzt oder sich mit der Programmierung nicht an den Standard hält.
Letztlich halte ich es auf jeden Fall für besser, erstmal "sauberes C++" zu programmieren und "im Fall des Falles" C-APIs an den entscheidenden Stellen zu stricken .... selten weiß man im Vorhinein, wo und wie man welche "Fremdmodule" dranpflanschen muss.Gruß,
Simon2.
-
Naja - aber nur, wenn man auf Link- oder Laufzeitebene ansetzt
Was meistens der Fall ist, wenn man den Compiler nicht vorschreiben will / kann
Bei uns halt tiefgreifendes Problem. Wir schreiben Anwendungen, die durch Module erweitert werden koennen / müssen. Die Module schreiben teilweisse auch externe Firmen. Den wiederum kannst ned vorschreiben, was fuern compiler sie zu verwenden haben.
Will damit ja nur sagen, dass man leider noch auf das gute alte C angewiesen ist, solange sich da bei der standartiesierung nix tut. Und denk mal das das nicht wenige praxisorientierte Projekte betrifft.
Ciao ...
-
Wenn der Sourcecode nicht bereit gestellt wird, kann das tatsächlich zu einem Konflikt führen. Aber für den übernächsten C++-Standard wird hoffentlich eine Sharedlibrary-Spezifikation rauskommen. Zumindest ist das auf der Todo-Liste des Komitees. Dann müsste sich dieses "Problem" in Luft auflösen? Hoffe ich zumindest, das da Nägel mit Köpfen gemacht wird. Vielleicht wird auch CLI Einzug halten? Naja, solange müssen wir uns noch gedulden oder selber Proposals einreichen.
-
@Simon2,
Konstruktor schön und gut, aber dort musst du dann trotzdem die Nullen reinsetzen ^^class ClassX { public: ClassX() { std::fill(m_IntegerArray, m_IntegerArray + 10, 0); } private: int m_IntegerArray[10]; const static int m_nLength = 10; public: void display(); void edit(); }void ClassX::display() { for(int i = 0; i < m_nLength; ++i) { std::cout << m_IntegerArray[i] << " "; } std::cout << std::endl << std::endl; } void ClassX::edit() { display(); // Und dann das editieren ^^ }Wenn die Grösse konstant ist, wirst du ja wohl nicht einen Vektor nehmen. Und womöglich muss der Benutzer zuerst die 10 Integer-Werte einfüllen. Er soll sie aber auch bearbeiten können. Alles funktioniert also über die gleiche Funktion, bearbeiten und erste Mal befüllen. Dabei wird zuerst das Array ausgegeben. Damit es halt ein wenig schön aussieht, wäre es nett, wenn es standard mässig mit 0s gefüllt ist.
Grüssli
-
Hallo
Dravere schrieb:
Wenn die Grösse konstant ist, wirst du ja wohl nicht einen Vektor nehmen
Warum? Ich nehme immer vector oder halt andere container, aber keine normalen arrays mehr.
chrische
-
Dravere schrieb:
@Simon2,
Konstruktor schön und gut, aber dort musst du dann trotzdem die Nullen reinsetzen ^^Nö, das meinte Simon2 nicht. Sondern sowas (das ist jetzt echt nur zur Veranschaulichung und heißt nicht, das man solche Typen bauen muß!!! Aber wer will... kann das machen):
class Integer { int value; public: Integer() { value = 0; } // zusätzlich noch die Operatoren wie +, -, = usw. überladen!!! }; Integer a[10]; // autom wird der Ctor aufgerufen und 0 initialisiert cout << a[0] ; // gibt 0 aus a[0] = 2; cout << a[0]; // gibt 2 ausVorteil bei C++ ist halt, das alle Klassen als Build-in-Types designed werden können.
Dravere schrieb:
Wenn die Grösse konstant ist, wirst du ja wohl nicht einen Vektor nehmen. Und womöglich muss der Benutzer zuerst die 10 Integer-Werte einfüllen.
Nein, bei Vector ebend nicht:
vector<int> a(10,0); // 10 Elemenete mit 0 initialisierenDravere schrieb:
Damit es halt ein wenig schön aussieht, wäre es nett, wenn es standard mässig mit 0s gefüllt ist.
Bei ISO-C++ lautet die Devise: bezahle nur für das, was du auch haben willst. Da das initialisere von solchen Arrays zur Laufzeit Rechenzeit kostet, wird das ebend nicht standardmäßig gemacht. Wenn du es haben willst, kannst du es aufrufen und bekommst es auch. Notfalls bauste dir einen eigenen Typ, der im Ctor alles macht, was du haben willst. Für dich, der es benutzt, ist es dann egal ob du int oder Integer benutzt. Oder du machst ein std::fill.
-
RHBaum schrieb:
...Den wiederum kannst ned vorschreiben, was fuern compiler sie zu verwenden haben. ...
Nee, braucht man auch nicht. Sourcecode (inkl. Std-Makefile) geben und fertig. Sofern man sich an den Standard gehalten hat, dürften die auch keinen Probleme haben.

RHBaum schrieb:
...
Will damit ja nur sagen, dass man leider noch auf das gute alte C angewiesen ist, ...Definitiv richtig !
Ich glaube, selbst wenn die C++-Standardisierung da noch was nachbessert, wird C (zumindestens) für APIs noch sehr lange benötigt werden (allein schom weil sie etabliert ist).Ich sehe und teile Deinen Punkt - es ist für mich nur kein Argument, prinzipiell nach einem calloc-Pendant in C++ zu suchen.
Gruß,
Simon2.
-
Dravere schrieb:
@Simon2,
Konstruktor schön und gut, aber dort musst du dann trotzdem die Nullen reinsetzen ^^class ClassX { public: ClassX() { std::fill(m_IntegerArray, m_IntegerArray + 10, 0); } private: int m_IntegerArray[10]; const static int m_nLength = 10; public: void display(); void edit(); }...
Was Du da ber tust, ist nicht "Speicherbereiche auf 0 setzen", sondern Objekte !
hier sind's halt ints, aber der code würde exakt so funktionieren, wenn Du stattdessen irgendwelche selbstgebastelten Klassen (und leicht verallgemeinert sogar mit nahezu beliebigen Containern statt build-in-arrays) nähmst.
Der Unterschied wird vielleicht noch deutlicher, wenn Du nicht auf 0, sondern z.B. auf 10 setzen wollen würdest: Mit memset() kämst Du da in Teufels Küche und müsstest Dich mit der interenen Repräsentation Deines Datentype auseinandersetzen.
Mit std::fill wäre das lediglich das Hinzufügen einer '1'.
Dravere schrieb:
...Damit es halt ein wenig schön aussieht, wäre es nett, wenn es standard mässig mit 0s gefüllt ist.
Grüssli
Das mag Deinem persönlichen Standard und ästhetischem Empfinden "schön" sein, ich halte das für irgendwas zwischen "überflüssig", "verwirrend" und "gefährlich" (spätestens dann, wenn man beginnt sich darauf zu verlassen, dass ja "alles schon genullt ist") ....
Der (C++-)Standard sieht für die Initialisierung von Objekten dn Konstruktor vor und geht davon aus, dass dort Daten auf einen fachlich sinnvollen Wert gesetzt werden ... ob das 0 ist, sollte man IMO von Fall zu Fall entscheiden.Gruß,
Simon2.
-
Artchi schrieb:
Dravere schrieb:
@Simon2,
Konstruktor schön und gut, aber dort musst du dann trotzdem die Nullen reinsetzen ^^Nö, das meinte Simon2 nicht. Sondern sowas (das ist jetzt echt nur zur Veranschaulichung und heißt nicht, das man solche Typen bauen muß!!! Aber wer will... kann das machen):
class Integer { int value; public: Integer() { value = 0; } // zusätzlich noch die Operatoren wie +, -, = usw. überladen!!! };Auf die Idee wäre ich nie gekommen ^^
Aber ob das wirklich sinnvoll ist, ob es nicht leichter ist einfach einen int zu benutzen und ihn halt zu initialisieren. Naja, kann man wohl drüber streiten
Artchi schrieb:
Dravere schrieb:
Wenn die Grösse konstant ist, wirst du ja wohl nicht einen Vektor nehmen. Und womöglich muss der Benutzer zuerst die 10 Integer-Werte einfüllen.
Nein, bei Vector ebend nicht:
vector<int> a(10,0); // 10 Elemenete mit 0 initialisierenOk, die zwei Sätze waren ein wenig misslungen. Deshalb nochmals ein wenig anderst ausgedrückt:
Du nimmst ja wohl nicht einen vector, wenn die Grösse konstant bleibt?
Oder anderst gesagt, der zweite Satz hat nix mit dem ersten zu tun
Bzw. Chrische5 hat mich korrekt verstanden. Daher noch einen kurzen Einschub:
Braucht ein Vektor nicht noch zusätzlichen Platz? Z.b. zum speichern der Länge? Oder noch ein paar weitere Informationen? Ein Array sind ja nur die Objekte im Speicher hintereinander, mehr nicht.Artchi schrieb:
Dravere schrieb:
Damit es halt ein wenig schön aussieht, wäre es nett, wenn es standard mässig mit 0s gefüllt ist.
Bei ISO-C++ lautet die Devise: bezahle nur für das, was du auch haben willst.
Und das will ich haben, denn ich will das je nach dem, dem User auch angenehm vor die Nase werfen *g*
Ich werde sicher nichts mit 0 initialisieren, wenn ich es später sowieso mit einer 1 überschreibe, wäre ja Unsinn.@Simon2,
Hmmm, stimmt! Das sind Objekte und nicht der eigentliche Speicher. Aber wenn ich ehrlich bin, habe ich memset, nie für etwas anderes als 0 benutzt. Vor allem für die structs in der WinAPI, bis ich das ZeroMemory entdeckt hatte ^^
Die structs in C++, kann ich aber mit einem Konstruktor versehen oder gleich als Klasse nehmen. Ok, so langsam wird mir da einiges klar, vor allem auch, wieso man diese C-Funktionen sein lassen kann *g*Simon2 schrieb:
Der (C++-)Standard sieht für die Initialisierung von Objekten dn Konstruktor vor und geht davon aus, dass dort Daten auf einen fachlich sinnvollen Wert gesetzt werden ... ob das 0 ist, sollte man IMO von Fall zu Fall entscheiden.
Das war mir dagegen schon klar. Das mit dem 0 war einfach nur so als Beispiel. Ich initialisieren die Dinger schon so, dass sie auch sinnvoll initialisiert sind. Steht aber in diesem Beitrag schon weiter oben

Sooooo dumm bin ich auch wieder nicht
Grüssli
-
Dravere schrieb:
...
Sooooo dumm bin ich auch wieder nicht
Grüssli
Ach, mit "dumm" hat das nicht unbedingt was zu tun. In C ist das mitunter guter Stil (konkret hatten wir schonmal ein Produktionsproblem, das durch nicht initialisierten Speicher zustandekam) .... aber eben nur, weil es keine Konstruktoren gibt, die die Objektinitialisierung an zentraler Stelle sicherstellen.
... und das kenne ich schon von "C-Recken", dass sie gerne auch in C++, Java, ... "erstmal Speicher auf 0 setzen" wollen.Ergo: Nicht Dumm-, sondern Gewohnheit.

Ob das bei Dir der Fall ist, weiß ich nicht, aber Dein "ist doch schön so", ließ es mich vermuten....
Gruß,
Simon2.
-
Dravere schrieb:
Auf die Idee wäre ich nie gekommen ^^
Aber ob das wirklich sinnvoll ist, ob es nicht leichter ist einfach einen int zu benutzen und ihn halt zu initialisieren. Naja, kann man wohl drüber streiten
Ja, kann man drüber streiten. In anderen Sprachen ist das sogar gleich mit dabei: in Java gibts die Klasse java.lang.Integer, in C# ist jedes Integer autom. ein Objekt. Also sowas wäre in C# möglich:
5.toString(); // 5 ist implizit ein Integer-Objekt.Ist in Ruby auch so.
Wenn es nach den Hardcore-OO-Programmierern geht, würden die bei sowas jubeln.
Deshalb habe ich geschrieben, das wer das haben will, durchaus so machen kann. Und das ist die Stärke von C++.Dravere schrieb:
Ok, die zwei Sätze waren ein wenig misslungen. Deshalb nochmals ein wenig anderst ausgedrückt:
Du nimmst ja wohl nicht einen vector, wenn die Grösse konstant bleibt?Braucht ein Vektor nicht noch zusätzlichen Platz? Z.b. zum speichern der Länge? Oder noch ein paar weitere Informationen? Ein Array sind ja nur die Objekte im Speicher hintereinander, mehr nicht.
Und wo merkst du dir die Array-Größe, wenn du ein Plain-Array benutzt? Spätestens dann, baust du ungewollt ein Vector nach. Mit dem Unterschied, das Vector schon seit 1998 implementiert, getestet und sich bei Mio. anderen Programmen bewährt hat. Wenn du ein Array anlegst, das schon zur Compilerzeit eine bestimmte Größe hat (also ohne new), dann _kann_ man über den Vector-Einsatz streiten. Aber selbst da, mußt du doch irgendwo immernoch die Größe wissen? Niemand legt ein Array an, ohne die Größe später zu kennen. Und da würde ich heute std::tr1::array einsetzen. Plain-Arrays machen heute irgendwie keinen wirklichen Sinn. Weil man dann spätestens vector oder array ungewollt nachbaut.
Also, von der Codegröße oder Resourcenverschwendung mach vector nicht viel aus, weil du indirekt wieder Vorteile bekommst. Das gibt ein Nullsummenspiel.
Du programmierst ja nicht auf einem 4 KByte-Embeddedcomputer, wo jedes Byte zählt. Da würde ich wirklich Plain-Array nehmen.
-
Simon2 schrieb:
Ergo: Nicht Dumm-, sondern Gewohnheit.

Und Gewohnheit, kann manchmal (nicht immer!) auch Dummheit oder sagen wir zumindest Faulheit bedeuten.

Simon2 schrieb:
Ob das bei Dir der Fall ist, weiß ich nicht, aber Dein "ist doch schön so", ließ es mich vermuten....
Das war auf den Benutzer bezogen. Für den User, welcher das Zeug editiert und sich in der GUI das Array anschaut, wäre es eben nett, wenn zu beginn das Array auf 0 gesetzt wurde. Manchmal wäre da auch eine 1 angebracht oder was auch immer, aber nicht irgendwelche -29532344 (nur reingetippselt, keinen Grund auf Korrektheit, dass danach auch sowas dort steht)

@Artchi,
In Java ist aber auch ein int automatisch auf 0 gesetzt, nicht nur ein java.lang.Integer. Wenn ich mich richtig entsinne ^^
Und das mit C# ist auch in Java möglich *g*
Aber alles nebensächlich
Artchi schrieb:
Wenn es nach den Hardcore-OO-Programmierern geht, würden die bei sowas jubeln.
Deshalb habe ich geschrieben, das wer das haben will, durchaus so machen kann. Und das ist die Stärke von C++.Und deswegen liebe ich C++. Ich mag die Freiheit. Deshalb wäre eigentlich Assembler noch angebrachter, aber das ist mir dann schlussendlich irgendwo zu mühsam *g*
Artchi schrieb:
Du programmierst ja nicht auf einem 4 KByte-Embeddedcomputer, wo jedes Byte zählt. Da würde ich wirklich Plain-Array nehmen.
Das finde ich eine etwas heikle Sache. Nur weil wir heute sehr grosse Mengen an Ressourcen zur Verfügung haben, heisst dies auch, dass wir diese verschwenden dürfen? Klar, in dem Bereich ist es wirklich nichts all zu grosses, doch es fängt meistens bei den kleinen Dingen an.
Ich würde einfach sehr gern so ressourcenfreundlich wie nur möglich programmieren. Bin zwar davon noch weit entfernt
Gerade auch für später, wenn ich mal wirklich grössere Programme schreibe, dann bin ich mir bereits gewöhnt auf den Speicher zu achten ^^Grüssli
-
Dravere schrieb:
Simon2 schrieb:
Ergo: Nicht Dumm-, sondern Gewohnheit.

Und Gewohnheit, kann manchmal (nicht immer!) auch Dummheit oder sagen wir zumindest Faulheit bedeuten. ;)...
... und manchmal auch "Erfahrung".

Dravere schrieb:
...Für den User, welcher das Zeug editiert und sich in der GUI das Array anschaut, wäre es eben nett, wenn zu beginn das Array auf 0 gesetzt wurde. Manchmal wäre da auch eine 1 angebracht oder was auch immer, ...
Oder eben auf "Nicht verfügbar" oder die jeweilige PLZ oder ...

Eben auf den fachlich sinnvollen Defaultwert ... den man schön im Konstruktor setzen kann (und fast niemals mittels memset()).
Dravere schrieb:
...
Artchi schrieb:
Du programmierst ja nicht auf einem 4 KByte-Embeddedcomputer, wo jedes Byte zählt. Da würde ich wirklich Plain-Array nehmen.
Das finde ich eine etwas heikle Sache. Nur weil wir heute sehr grosse Mengen an Ressourcen zur Verfügung haben, heisst dies auch, dass wir diese verschwenden dürfen? ...
Du musst aber konsequenterweise auch die Entwicklungs-, Debugging-, Test-, Wartungs-, Weiterentwicklungs- und "Übertragungs"-aufwände (wenn mal jemand Anders an dem Programm arbeiten muß) betrachten. Zusammen mit Stabilität sind das Faktoren, die in der Praxis deutlich wichtiger sind als ein paar gesparte KB.
Gruß,
Simon2.
-
Ich weiß ja nicht ob du die ganzen Sicherheitsloch und Bufferoverflows auf heise-Security kennst? Denk mal darüber nach, warum es gesünder sein kann, etwas mehr Resourcen zu verschwenden (vector) anstatt sich mit einem Plain-Array abzukrepeln und in Produktion gibts dann doch nen Bufferoverflow... weil das eine Byte wichtiger war. Gewonnen hat man aber irgendwie nichts.