Was passiert bei XXX *p =new XXX[0]; ?



  • Hi,

    ist das nicht sogar durch den Standard verboten ? Ich meinte, da mal so eine Technik gesehen zu haben (zur Umsetzung von Typanforderungen an templlate-Argumente), die darauf basierte ... bin mir aber nicht ganz sicher.

    Gruß,

    Simon2.



  • Du bekommst einen Pointer auf ein Array der Größe 0. Das darf kein Nullpointer sein.



  • also ich kann so etwas noch nicht einmal kompilieren...



  • ich hatte in einem Programm mal folgenden Code:

    VertexBuffer = new Vertex[numOfVertices];
    

    und davor keine Überprüfung ob numOfVertices > 0 ist. Ist numOfVertices == 0 hat es auch funktioniert ohne Probleme - benutzt hab ich dazu MSVC 2005

    ich meine gelesen zu haben was Bashar schon gesagt hat: "Du bekommst einen Pointer auf ein Array der Größe 0. Das darf kein Nullpointer sein."



  • Genau, du bekommst einen Pointer. Das einzige was du mit dem machen darfst ist seinen Wert zu verwenden (muss AFAIK eindeutig sein), und ihn mittels "delete []" wieder freigeben. Dereferenzieren darfst du ihn auf jeden Fall nicht. Erlaubt ist es aber.



  • HI,

    ja, mir ist gerade aufgefallen, dass in "meinem Beispiel" der Fall ein wenig anders gelagert war, da dort Stackarrays verwendet wurden:

    int a[0];
    

    ... und IIRC führt das zu einem compile-Fehler.

    Gruß,

    Simon2.



  • Simon2 schrieb:

    ja, mir ist gerade aufgefallen, dass in "meinem Beispiel" der Fall ein wenig anders gelagert war, da dort Stackarrays verwendet wurden:

    int a[0];
    

    ... und IIRC führt das zu einem compile-Fehler.

    Korrekt. In Standard-C++ sind solche (also nicht mit new erzeugte) "zero-sized"-Arrays nicht erlaubt. Sie sind aber eine sehr sinnvolle (low-level)-Erweiterung, die nahezu jeder Compiler bietet. Für gewöhnlich setzt man solche Arrays ein, wenn man Strukturen mit einer variablen (dynamisch festgelegten) Größe benötigt.



  • Naja, meistens tuts es auch wenn man statt [0] einfach [1] nimmt 😉



  • HumeSikkins schrieb:

    Für gewöhnlich setzt man solche Arrays ein, wenn man Strukturen mit einer variablen (dynamisch festgelegten) Größe benötigt.

    Was meinst Du damit genau? Geht es einfach nur darum den Sonderfall Größe 0 durch den normalen Codepath mit abzudecken? Oder steckt da was tieferes dahinter?



  • @Jester
    Ich meine damit sowas:

    struct Foo {
      unsigned size_;
      Type data_[0];
    };
    
    int main() {
       // Note: sizeof(Foo) is typically == sizeof(size_)
       unsigned s = readSize();
       void* p = operator new(sizeof(Foo) + s * sizeof(T));
       Foo* f = new (p) Foo;
       readData(f);
       for (unsigned i = 0; i < f->size_; ++i) {
          doSomething(f->data_[i]);
       }
    
    }
    

    Vorteil: nur eine new-Allokation und bessere Cache-Effizienz bei Zugriff auf Foo, da "Header" und Daten in einem sequentiellen Speicherbereich liegen. Aber wie gesagt: das ist eine Low-Level-Optimierung.

    Naja, meistens tuts es auch wenn man statt [0] einfach [1] nimmt


Anmelden zum Antworten