Array mit NULL initialisieren



  • davie schrieb:

    das andere: sieht verdächtig nach einer verletzung der odr aus, in headerdateien solltest du deine variablen eigentlich nur deklarieren.

    Aber deshalb habe ich in meiner Header-Datei nur Cell *cellPointer[26]; stehen. Im Konstruktor der implementierenden Klasse mache ich es nun so, wie Glamdrink gesagt hat:

    for(int a=0; a<26; a++) {
    
       this->cellPointer[a] = NULL;
    }
    

    Das funktioniert nun auch einwandfrei. Ist das in Ordnung so? Ich deklariere ja in der Header-Datei nur ein Array mit einer bestimmten Größe, oder?



  • Stefano2 schrieb:

    Aber deshalb habe ich in meiner Header-Datei nur Cell *cellPointer[26]; stehen.

    Das ist eine Definition.

    Im Konstruktor der implementierenden Klasse mache ich es nun so, wie Glamdrink gesagt hat:

    Sit cellPointer global oder Member einer Klasse?



  • Stefano2 schrieb:

    this->cellPointer[a] = NULL;
    

    das sagt mir, dass cellPointer eine membervariable ist und damit alles in ordnung bleibt. odr-gefährlich würde es erst mit einer globalen variable werden.

    this-> kannst du übrigens ruhigen Gewissens weglassen.



  • Wofür steht ODR?





  • kingruedi schrieb:

    std::memset(cellPointer,0,26);
    

    Das geht aber nur auf Plattformen, auf denen ein Nullzeiger zufällig 0x00 entspricht und vor allem sizeof(Cell*) == sizeof(char) gilt 😉

    Dann lieber:

    #include <algorithm>
    
    std::fill_n(cellPointer, 26, NULL);
    


  • ha, was für ein gemeines teil code du uns da anbieten willst 😉



  • ups, vergessen weiterzuschreiben 🙄
    static_cast<int*>



  • operator void schrieb:

    Das geht aber nur auf Plattformen, auf denen ein Nullzeiger zufällig 0x00 entspricht

    nee, die Diskussion gabs schon öfter und wenn mich nicht alles täscht steht im Standard das 0 auch der Nullzeiger ist.



  • *ups*

    std::memset(cellPointer,0,26*sizeof(Cell*));
    

    sollte das natürlich sein

    und NULL muss laut Standard 0 sein! NULL ist doch AFAIK sogar deprecated (wobei ich gestehen muss, dass ich selber lieber NULL für Pointer benutze, da es IMHO verständlicher ist)



  • Dass man eine literale 0 in einen Zeiger casten kann, ist mir bewusst - ich verwende auch immer 0 statt NULL. Aber das heißt ja nicht, dass der Nullzeiger im Speicher auch wirklich nur aus 0en besteht. Das meinte ich mit 0x00; natürlich ist "int* p = 0x00" im Code auch der Nullzeiger. Aber reinterpret_cast<long>(p) muss nicht unbedingt 0l sein.



  • verstehe ich nicht, wieso soll man memset(NULL) statt 0 schreiben 😕



  • jaja, der nullzeiger.
    nicht vergessen es handelt sich dabei nur um einen konstanten integralen ausdruck (definiert in 5.19/3), der als 0 ausgewertet wird und in einem zeigertyp (den null zeiger dieses typs) konvertiert werden kann (solange es ein rvalue und eine integral constant expression ist)

    siehe dazu auch 4.9/1

    deshalb nützt es auch nichts, dem lieben fill_n NULL oder 0 zu übergeben, da damit
    fill_n <int*, int, (const) int> aufgerufen wird, und das dritte argument die auflagen nicht mehr erfüllt, implizit in einen null zeiger umgewandelt werden zu können.



  • DrGreenthumb schrieb:

    verstehe ich nicht, wieso soll man memset(NULL) statt 0 schreiben 😕

    der einzige sinn dahinter ist wohl, darauf aufmerksam zu machen, dass man ein array von zeigern initialisieren möchte, die alle auf adresse 0 zeigen sollen.



  • ja.. ich habe operator void so verstanden, dass es auf irgendwelchen wilden architekturen nicht funktionieren könnte wenn man 0 schreibt.



  • ja, weil nicht definiert ist, wie ein null zeiger wert für einen zeiger auf ein objekt aussehen muss, es ist nicht einmal garantiert, dass

    int *x = 0;
    float *y = 0;
    

    x und y auf der selben architektur tatsächlich nur durch 0en im Speicher dargestellt werden, bzw. dass x intern genauso wie y dargestellt wird.
    0 ist in erster linie aber eine ganzzahlige konstante und wird auch dementsprechend interpretiert.

    der standard sagt nur, dass ein "null pointer value" (= der (zeiger)wert für einen bestimmten typ, zu dem jeder ganzzahliger konstante ausdruck evaluiert wird) mit keinem anderen (zeiger)wert kollidiert.



  • 😕 😕

    muss ich memset jetzt NULL, oder darf ich auch 0, übergeben?



  • egal, beides evaluiert zu einem int, der 0 ist; damit ist die funktion nicht geeignet, zeiger auf ihren null zeiger wert zu setzen.



  • @DrGreenthumb
    wenn eine Architektur die NULL Pointer in wirklichkeit mit einem anderen Wert belegt, dann gehen beide Varianten nicht.

    std::memset(foo,reinterpret_cast<char>(reinterpret_cast<bar*>(NULL)),size);
    

    das könnte helfen, wenn das verwendete NULL-Muster sich nach einem ``char'' wiederholt 😉



  • Wie auch immer, ich hoffe, nullptr schaft es in den nächsten Standard.


Anmelden zum Antworten