Array: Mehr Felder ansprechen als deklariert sind



  • Verlassen will ich mich da ja auch gar nicht drauf, eher im Gegenteil ich will es vermeiden.
    Nur interessiert es mich gerade wieso da aufeinmal Speicher frei ist wo ich was speichern darf..



  • Der Zugriff auf ein Feld jenseits der Arrygrenzen erzeugt undefiniertes Verhalten. Und das ist - naja - einfach undefiniert. Er könnte genausogut schon bei index 10 abstürzen, dich ewig weiter zugreifen lassen, oder, wenn der Compilerhersteller oder jemand anderes einen Clown gefrühstückt hatte deinen Rechner neustarten, deine Platte formatieren, Obama ne böse Mail schicken... undefiniert eben.
    Was vermutlich der Fall ist: Die Speicherplätze test[1] bis test[34] gehören noch deinem Programm - die danach nicht mehr. Deshalb gibts bei test[35] eine Zugriffsverletzung und aus. Der Speicher der Plätze 1 bis 34 wurde deinem Programm zugeteilt, deshalb darfst du da schreiben und lesen, allerdings sind sie nicht für deinen zugriff reserviert sondern für etwas anderes (ich würd auf Debugginginformationen oder irgendwelche Rücksprungadressen tippen), deshalb machst du dir da "nur" deinen Programmablauf mit kaputt.

    Allgemein gilt: lass es. Da kommt nichts gutes bei rum.



  • Hm und wie ist das bei negativen Indizes?
    Also irgendwo wird ja mein Programm bzw. die main-Funktion ja mal aufgerufen, d.h. mein Programm landet auf dem Stack richtig? Der Stack wächst ja immer zu den niedrigeren Adressen, also würde ich bei negativen Indizes erstmal leere Sachen überschreiben und irgendwann auf den Heap treffen oder? (Weil der Heap wächst ja zu höheren Adressen)
    Wenn ich jedoch positive Indizes nehme überschreibe ich die Rücksprungadresse etc. und gegebenenfalls sogar den Stack-Frame anderer Programme?



  • Pille456 schrieb:

    Hm und wie ist das bei negativen Indizes?

    nein, nein, nein. da könnte was anderes laufen. unter dos interrupts. unter win asynchronous procedure calls. haben die linuxer da auch was?



  • Hm ich habe noch nie mit negativen Indizes gearbeitet. Worauf greife ich denn genau zu, wenn ich z.B. test[-1] nutze?



  • Pille456 schrieb:

    Hm ich habe noch nie mit negativen Indizes gearbeitet. Worauf greife ich denn genau zu, wenn ich z.B. test[-1] nutze?

    auf das element vor test[0]. darfste halt nur machen, wenn test nur ein zeiger ist auf in ein anderes array rein.

    //strings in altem pascal waren ja so
    char pacalstringspeicher[256]={5,'h','a','l','l','o'};
    
    //in meiner api will ich immer zeiger auf den ersten buchstaben meinen
    //if(istPalindrom(pascalstringspeicher+1)...
    
    //uns schon hat man's
    bool istPalindrom(char* ps){
      for(int i=0;i<ps[-1]/2;++i)
        if(ps[i]!=ps[ps[-1]-i)
           return false;
      return true;
    }
    


  • Hmm das verstehe ich noch nicht so ganz. Was steht denn da? Da kann doch theoretisch alles Mögliche stehen oder nicht?

    int blub = 10;
    int test[1];
    test[0] = 0;
    test[1] = 1;
    std :: cout << test[-1]; //Kommt dann hier nun blub = 10 bei raus oder was?
    


  • Pille456 schrieb:

    Hmm das verstehe ich noch nicht so ganz.

    bin sicher, du schaffst das, wenn du es hundertmal durchliest.



  • Ein Array ist nichts weiter als ein Zeiger auf das erste Element eines Speicherbereichs, der so groß ist, dass du dort so viele Elemente hintereinander unterbringen kannst, wie du angefordert hast.
    Aber dieser Speicherbereich liegt irgendwo im Speicher, sowohl davor wie auch dahinter können sich also noch beliebige andere Daten befinden. Das können andere Objekte auf dem Stack/Heap sein, das können Rücksprungaddressen, Debuginformationen oder ausführbarer Code sein.
    Dieser Speicherbereiche gehören nicht mehr deinem Array, sind aber durch die relative Adressierung trotzdem zu erreichen. Wenn du da etwas hinschreibst, stehen deine Chancen gut, irgendetwas Wichtiges über den Haufen zu schießen. Was du da überschreibst, kann je nach Wetterlage und Uhrzeit, verwendetem Compiler/Compilereinstellungen (Debug/Release) und Betriebssystem etwas anderes sein.
    Mal könnte es ein "unwichtiger" Wert sein, der für den weiteren Programmverlauf nicht (mehr) wichtig ist. Es könnte auch eine Rücksprungadresse sein, in dem Fall kracht es also erst später, nämlich beim Verlassen der Funktion. Es könnte irgendein Wert überschrieben worden sein, der nicht zum Programmabsturz führt, dafür aber zu unerklärbarem Programmverhalten an einer völlig anderen Stelle.
    Oder es ist eben so, dass der Speicher in der Nähe deines Arrays nicht mehr deinem Programm gehört. Das wäre der günstigste Fall, dann bekommst du den segmentation fault sofort und nicht erst später, an einer ganz anderen Programmstelle.



  • Nanyuki schrieb:

    Ein Array ist nichts weiter als ein Zeiger auf das erste Element eines Speicherbereichs, der so groß ist, dass du dort so viele Elemente hintereinander unterbringen kannst, wie du angefordert hast.

    Das trifft für dynamische (mit new[] bzw. malloc() ) angeforderte Speicherbereiche zu, aber nicht für die (statischen) Arrays. Ein Array an sich repräsentiert nämlich ein Objekt - und hat im Grunde genommen nichts mit einem Zeiger zu tun. Dass es implizit in einen Zeiger konvertierbar ist, ist wieder ein anderes Thema.

    Dem Rest kann ich aber so zustimmen.


Anmelden zum Antworten