int-Array Initialisieren

Gast #250869
Lesenswert?

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
Persönliche Seite #250870
Lesenswert?

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;
Gast #250871
Lesenswert?

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
Gast #250875
Lesenswert?

Ö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...
#250877
Lesenswert?

[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.
Gast #250878
Lesenswert?

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)...
Gast #250879
Lesenswert?

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
Gast #250881
Lesenswert?

> 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);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren