Hallo Spezialisten, wie kann ich in C++ ein Array aus int initialisieren? wie das mit 0 für jedes Feld geht, weiß ich? Aber wie initialisiere ich jedes Feld mit 1? int* pArray = new int[10]; memset(pArray, 0, sizeof(int) * 10); ergibt: -> pArray[0] = 0 -> . -> .. -> pArray[9] = 0 ich will aber 1 drinstehen haben! memset((int*)pArray, 1, 10) dann steht aber nur Müll drin. Kann mir jemand das erklären? Danke Euch Karin
memset beschreibt einzelne Bytes mit dem angegebenen Wert; in Deinem ersten Falle rufst Du das auch korrekt auf, in dem Du die Anzahl der zu beschreibenden Bytes mit "sizeof (int) * 10" bestimmst. Dein zweiter Versuch schlägt einerseits fehl, weil Du nur die ersten zehn Bytes des Arrays überschreibst, was, je nach sizeof (int) nur die ersten fünf oder gar nur zweieinhalb Arrayelemente überschreibt. Andererseits schlägt Dein Versuch fehl, weil Du den Arrayelementen nicht den Wert 1, sondern den Wert 0x0101 (bei sizeof (int) == 2) oder 0x01010101 (bei sizeof (int) == 4) zuweist. Das ist 257 oder 16843009. Verständlich? Du wirst Dein Array "von Hand" mit einer Schleife initialisieren müssen: for (i = 0; i < 10; i++) pArray[i] = 1;
Danke Rufus, ist das nicht so wie bei memcpy, daß der Cast angibt, das der Compiler in 4er Schritten gehen soll? Offenbar nicht, sehr performat ist das mit der Schleife dann nicht mehr... Karin
Nö, memset selbst erwartet einen Pointer auf einzelne Bytes. Sieh' Dir den Prototypen an. Da memset auch keine C++-Funktion ist, gibt es auch keine überladene Variante für andere Pointertypen.
Öhm, sorry, das ist flasch angekommen! Also: >sehr performat ist das mit der Schleife dann nicht >mehr... >Naja, was meinst Du denn, wie 'memset' arbeitet? Aus dem Bauch heraus würde ich vermuten, daß memset in etwa so implementiert ist:
1 | void memset(void *ptr, int val, size_t size) |
2 | {
|
3 | size_t ctr = 0; |
4 | for (;ctr < size; ctr++) |
5 | (int *)ptr = val; |
6 | }
|
Oder so ähnlich...
Der Typecast nach (int *) ist nicht korrekt; memset arbeitet mit einzelnen Bytes bzw. Zeichen.
[Quote] Aus dem Bauch heraus würde ich vermuten, daß memset in etwa so implementiert ist: void memset(void *ptr, int val, size_t size) { size_t ctr = 0; for (;ctr < size; ctr++) (int *)ptr = val; }Oder so ähnlich... [/Quote] Du hasst nicht aufgepasst! memset (wie alle Mitglieder der mem...() Familie) arbeitet auf Bytes nicht auf int!! Also wenn memset tatsächlich mit einer Schleife implementiert ist (*), dann ist es höchstens so implementiert:
1 | memset(void *ptr, int val, size_t size) |
2 | {
|
3 | size_t ctr = 0; |
4 | for (;ctr < size; ctr++) |
5 | (unsigned char *)ptr = val; |
6 | }
|
(*) Viele Prozessoren stellen für solche Aufgaben eigene Instruktionen zur Verfügung. Derjenige der Deine Standardbibliothek geschrieben hat, weiß das aber und verwendet diese auch. Gibt es sie nicht, so kommt halt obige Schleife zum Zug. Im übrigen haben Funktionen aus der mem...() Familie in C++ nichts mehr verloren, es sei dann man arbeitet auf tiefer Hardware-Ebene. Alles andere fällt mehr in die Kategorie: fahrlässige Programmierung.
Sorry, daß ich nicht aufgepasst habe ;-P Müsste da nicht noch ein Cast rein? Und zwar vor val, auf unsigned char? Aber das spielt auch - wie schon bemerkt - eigentlich keine Rolle, denn memset ist hier völlig fehl am Platze (selbst wenn man kein C++, sondern C Programmieren würde)...
Auf Intelbasierenden Achritekturen gibt es in Assembler einen Befehel STOS BYTE bzw STOS WORD in Verbindung mit REP kann dann ganze Speicherbereiche belegt werden (Store Single Byte/Wort) AL/AX gibt den Wert vor, ES:DI zeigt auf den Beginn in CX steht die Anzahl Bytes/Worte. damit ist ein memset innerhalb weniger Assemblerzeilen geschrieben Gruss
> Da memset auch keine C++-Funktion ist, gibt es auch keine > überladene Variante für andere Pointertypen. Für sowas gibt's in C++ std::fill und std::fill_n aus <algorithm>. Damit sähe der Code aus dem Originalposting dann so aus:
1 | int* pArray = new int[10]; |
2 | std::fill_n(pArray, 10, 1); |
Oder noch einfacher, mit vector statt einem Array:
1 | std::vector<int> pArray(10, 1); |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.