mikrocontroller.net

Forum: PC-Programmierung int-Array Initialisieren


Autor: Karin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Karin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, was meinst Du denn, wie 'memset' arbeitet?

Autor: Karin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@OldBug:

das war ja meine Frage, danke für die Wiederholung

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void memset(void *ptr, int val, size_t size)
{
  size_t ctr = 0;
  for (;ctr < size; ctr++)
    (int *)ptr = val;
}

Oder so ähnlich...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Typecast nach (int *) ist nicht korrekt; memset arbeitet mit
einzelnen Bytes bzw. Zeichen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
memset(void *ptr, int val, size_t size)
{
  size_t ctr = 0;
  for (;ctr < size; ctr++)
    (unsigned char *)ptr = val;
}


(*) 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.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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)...

Autor: T. Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: T. Stütz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry heißt natürlich "STOre String"

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
    int* pArray = new int[10];    
    std::fill_n(pArray, 10, 1);

Oder noch einfacher, mit vector statt einem Array:
    std::vector<int> pArray(10, 1);

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.