[C++] Alle Elemente eines Arrays mit -2 füllen.

  • Also, ich habe ein Array, das wie folgt aufgebaut ist.

    Code
    signed short tMap[11][11]


    Nun würde ich gerne jede Stelle des Array mit -2 füllen.
    Wenn dies nur beim erstellen des Arrays sein sollte, wäre das ja kein Problem, aber ich muss das Array leider sehr oft wieder auf den Ursprungszustand zurücksetzen.

    Da gibt es ja diese schöne Funktion void * memset(void * ptr, int value, size_t num).
    Ok, dann versuchen wir es mal.

    Code
    // delete old (and maybe wrong) map information
    		memset(this->map, -2, sizeof(this->map));


    Kompiliereb lässt es sich auch noch sehr gut.

    Zitat

    >> Set new map information ...
    Segmentation fault (core dumped)

    Ok, dann war ich ein wenig irritiert.
    Habe mir mal die Beschreibung von memset() genau durchgelesen.

    Zitat

    value
    Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.

    Interessant, scheint also, als ob man nur chars benutzen könnte ??
    Hat da Jemand eine Erfahrung / Idee wie man das lösen könnte ??
    Und bitte nicht mit Schleifen kommen, da auch später einige 5-6 dimensionale Arrays kommen ...

    Edit: fill_n() bringst auch nicht, das kann keine mehrdimensionalen Arrays füllen ...

  • Interessante Frage. Auch wenn ich mich noch nie damit beschäftigen musste (und ich grad im Prüfungsstress bin), dachte ich mir ich nehm mir mal ein paar Minuten um drüber nach zu denken.

    memset() nimmt die Zahl die ihr übergeben wird als unsigned char. Auf gut Deutsch: da unsigned char immer 1 Byte groß ist (bzw. sein sollte), werden die ersten 8 Bits der übergebenen Zahl (oder eben 1 Byte) genommen, und überall in jede Speicheradresse geschrieben.

    Ein short sollte üblicherweise 2 Byte groß sein.

    Wenn du jetzt beispielsweise als value 2 übergibst (was 00000010 Binär ist), wird das in beide Speicherzellen für dein short geschrieben. Ergibt 00000010.00000010.
    Ein cout auf irgendeine Stelle der map wird 514 ergeben (das ist die Zahl da oben Binär).

    [-Anmerkung: Unterschied zw. Little Endian & Big Endian gibts hier nicht-]

    Damit wäre geklärt was genau in die Speicherzellen geschrieben wird. Nur du willst eine negative Zahl speichern. Das ist jetzt doch um einiges schwieriger.

    Bei Intel Maschinen werden negative Zahlen als Zweierkomplement abgelegt.

    [-Zweierkomplement: Bits negieren und + 1 / erstes Bit gibt Vorzeichen an-]

    Übergibt man nun -2 an memset, was das Zweierkomplement von 2 ist (also 11111110), werden diese Bits in beide Speicheradressen geschrieben. Ergibt 11111110.11111110.

    Ein cout auf irgendeine Stelle der map ergibt jetzt -258, da das erste Bit die negative Zahl einleitet, und vom Rest das Zweierkomplement (hier x0000001.00000010) den Wert angibt = 258.

    Jetzt zu deiner -2 die überall stehen soll: dafür müsste 11111111.111111110 in den Speicherzellen stehen. Das schaffst du aber nicht, da das unterschiedliche Bytes sind, und memset immer die gleichen in die Speicheradressen schreibt. Ich bin mir daher ziemlich sicher, dass das mit memset unmöglich zu bewerkstelligen ist.

    Getestet hab ich das mit

    Das bestätigt meine Überlegungen. Hatte nie Zugriffsverletzungen...
    (Getestet: 32 Bit Intel System (= Little Endian) mit msvc2005 Compiler)

    Wichtig: bitte schlagt mich nicht, falls irgendwo ein Denkfehler drin ist...

  • Soweit ich weis, stimmt das.
    Hab mal was rausgefunden.
    Immer wenn ich in map (neuer version: mapField) schreiben möchte gibt es den Fehler.
    Lesen kann ich jedoch da raus.

    Code
    typedef short tMapField[11][11];

    Edit: Ich bin so was von doof -.-''
    Ich hab einfach nur vergessen eine Referenz auf die Klasse zu setzen.
    Folglich hatte ich keine Schreibrechte ...