feld-inhalt per memset initialisieren klappt nicht ...
-
hallo,
sehe der wald vor lauter baeumen nicht:
// /////////////////////////////////////// int main( int argc, char *argv[] ) // /////////////////////////////////////// { ushort tmp[MAX_FIELD]; memset(tmp,(ushort)0x6, MAX_FIELD * sizeof(tmp[0]));nach ausfuehrung von memset beinhalten alle felder von tmp den wert 0x0606 !?!?!
was mache ich falsch?
danke vorab.
-
den vollstaendigen beispielcode:
// /////////////////////////////////////// int main( int argc, char *argv[] ) // /////////////////////////////////////// { const ushort MAX_FIELD = 14; ushort tmp[MAX_FIELD]; memset(tmp,(ushort)0x6, MAX_FIELD * sizeof(tmp[0])); return 0; }
-
memset setzt den wert byteweise. Dein 0x6, das du ja in ushort castet, castet dir memset einfach in unsigned char um, und setzt jedes byte mit 0x6.
Schau dir mal std::fill an, das macht das, was du willst
-
danke fuer die rasche antwort.
hast recht, memset arbeitet byteweise.statt memset muesste es also sein:
std::fill(tmp, tmp+MAX_FIELD, 0x6);da benutzt man jahrelang memset um feldinhalte auf 0 zu setzen, und wenns mal was anderes sein soll, merkt man erst, dass man die arbeitsweise von memset garnicht so wahrgenommen hat

vielen dank.
-
Wobei i.d.R. ein
memset( ,0, )intern versucht die Registerbreite des Prozessors ausnutzen. Der std::fill vermutlich ebenso.
-
Was spricht denn eigentlich dagegen, STL-Container zu verwenden?
std::vector<ushort> tmp(MAX_FIELD,0x6);ist doch viel kompakter zu schreiben und sagt genau das aus, was du willst.
(alternativ kannst du auch mit array<> arbeiten, wenn dir feste Größe reicht (afair in Boost, TR1 oder dem neuen Standard verfügbar))
-
immer wieder bemerkenswert in was fuer komischen schleifen man denkt:
das einfachste ist natuerlich ein STL-vector mit der vorgeschlagenen
konstruktion und reicht voellig aus.vielen dank.
-
wo wir beim thema memset sind
sowas ist ja nicht gerade ratsam hier:
struct Foo { int a; int b; char c; double d; // ;) std::string tanga; Foo(void) { memset(this, 0, sizeof(*this)); // NICHT NACHMACHEN ! } };da es ja C-Style ist. gibt es da eine einfache möglichkeit alles auf 0 zu setzen
und da genau das hier bei dem std container gehörig crashen wird, soll dieser per standard konstruktor initalisiert werden...
geht sowas recht einfach?
-
Skym0sh0 schrieb:
da es ja C-Style ist. gibt es da eine einfache möglichkeit alles auf 0 zu setzen
Klar. Alles mit 0 initialisieren.
Es gibt zB die möglichkeit eine ZeroFill Klasse zu schreiben:
//roher draft template<typename T> class ZeroFill { private: T obj; public: ZeroFill() : obj(0) {} operator T() { return obj; } };Einfach immer bei der Initialisierung zuweisen. Objekte sollten sowieso einen sinnvollen Default CTor haben der die Werte mit 0 oder etwas ähnlichen initialisiert sofern es vernüfntige default Werte gibt.
Deshalb habe ich sowas ehrlich gesagt noch nie gebraucht.
-
na mir gehts dabei eher so um sachen wie structs
weil 10 ints und floats und strings und so per init liste zu initialisieren ist eine ganz schöne schreibarbeit. und genau die will ich mir ersparen(ja ich weis ist and er falschen stelle gespart)...
-
Skym0sh0 schrieb:
na mir gehts dabei eher so um sachen wie structs
weil 10 ints und floats und strings und so per init liste zu initialisieren ist eine ganz schöne schreibarbeit. und genau die will ich mir ersparen(ja ich weis ist and er falschen stelle gespart)...Im Prinzip macht das der Default-Konstruktor für dich. Außer bei PODs, da gibt es Sonderregeln. In Kurzform:
struct S // POD { int i; float f; bool b; }; ... S s1; // #1 -> Werte der Member sind unbestimmt S s2 = S(); // #2 -> Werte der Member sind garantiert 0 bzw. falseSchon wenn du Strings drin hast, ist die Klasse aber kein POD mehr (PODs dürfen nur PODs enthalten), womit auch Variante 1 die Werte garantiert mit 0 initialisiert. Wenn du darauf Wert legst, kannst du den POD-Status auch auf andere Weise aufheben, z.B. (glaube ich) mit einem user-defined Konstruktor, der auch einfach leer sein kann.
Edit: nein, ich glaube mit C++0x wurde die POD-Definition derart erweitert, dass sie auch triviliale Konstruktoren einschließt. Da weiß ich dann die genauen Regeln nicht.
-
Wenn du mutig bist, kannst du in einer Klasse (ohne vtable) alle pods vor den nicht pods deklarieren und dann mit offsetof den Bereich für ein memset bestimmen.
Das Ganze müsste natürlich gut dokumentiert sein.Aber ich würds nicht machen, war auch nur eine Idee. Und ich glaube auch kaum, dass soetwas in der Praxis irgendow auch wirklich durchgeführt wird.
Und außerdem kann eine gute IDE mit guten Addons (bspw. MSVS + Visual Assist) bei solchen Fleißarbeiten ungemein hilfreich sein.
-
Skym0sh0 schrieb:
na mir gehts dabei eher so um sachen wie structs
weil 10 ints und floats und strings und so per init liste zu initialisieren ist eine ganz schöne schreibarbeit. und genau die will ich mir ersparen(ja ich weis ist and er falschen stelle gespart)...Wenn es eine POD struct ist, ist memset ja ok. Ansonsten: schreib ne Klasse ZeroFill oder aehnliches und mach die Struct dann so:
struct Foo { ZeroFill<int> a; ZeroFill<char*> b; ZeroFill<double> c; };