2016-07-11 1 views
5

Folgende ist ein sehr einfaches C-Programm:Speicher von Daten (string) außerhalb der Grenzen in einem dynamisch zugeordneten Array

char *p = (char*)calloc(5,sizeof(char)); 
strcpy(p,"Elephant"); 
printf("String = %s\n", p); 
p[6] = 'D'; 
printf("String = %s\n", p); 

die eine char Array von 5 Elementen calloc zuordnet() und verwendet strcpy() zu kopieren, eine Zeichenfolge in das Array. Es folgt die Ausgabe:

String = Elephant 
String = ElephaDt 

klar, bat ich für 5 char Elemente nur und daher neugierig zu wissen, warum die OS-Speicher mgmt mir mehr Elemente aus den Grenzen des dynamisch zugewiesenen Raum in p zu speichern erlaubt . Wenn ich nur einen Raum von 5 Zeichen zugewiesen bekommen habe, wie konnte strcpy() eine noch größere Zeichenfolge "Elephant" speichern, die länger als 5 Zeichen ist?

+4

C haben keine Grenzen-Überprüfung, der Compiler wird nicht beschweren (oder wirklich wissen), wenn Sie außerhalb der Grenzen schreiben. Das führt jedoch zu * undefiniertem Verhalten *, also tu es nicht. –

+0

@Joachim Pileborg "wird sich nicht beschweren ... wenn Sie außerhalb der Grenzen schreiben" ist definiertes Verhalten. Natürlich spezifiziert C keine Grenzen-Überprüfung, aber ein Compiler kann es verwenden. Außerhalb der Grenzen schreiben ist UB. – chux

+0

"warum die OS-Speicherverwaltung mir erlaubt, mehr Elemente außerhalb der Grenzen des dynamisch zugewiesenen Speicherplatzes in p zu speichern." -> Was haben Sie erwartet, dass der Code in einer solchen Situation benötigt wird? – chux

Antwort

5

Wenn Speicher zugewiesen wird, erfolgt dies in der Regel über einen Speichermanager. Diese weisen dem Betriebssystem häufig größere Speicherbereiche zu und geben diese dann in kleineren Teilen an malloc() und Freunde weiter.

Die 5 Byte, die Sie zugewiesen haben, sind daher sehr wahrscheinlich Teil eines größeren Speicherbereichs. Da Sie die Grenzen Ihrer Zuweisung verletzt haben, aber nicht des größeren Chunks, stört das Betriebssystem nicht. Es kann jedoch bedeuten, dass Sie anderen Speicher Ihres eigenen Programms beschädigt haben, indem Sie eine Zuteilung in der Nähe überschreiben. Es kann sogar bedeuten, dass Sie die Daten beschädigt haben, die der Speichermanager verwendet, um den zugewiesenen und freien Speicher zu verfolgen. Aber das ist nicht selbstverständlich. Es ist einfach undefiniertes Verhalten.

Undefiniertes Verhalten bedeutet nicht, dass Sie einen Laufzeitfehler erhalten müssen. Es kann genauso gut heißen, dass nichts passiert, oder dass du WW3 startest, oder was auch immer. Es ist nicht definiert, aber es bedeutet nicht unbedingt einen Absturz.

2

Sie werden sich daran gewöhnen müssen, wenn Sie in C programmieren wollen. Es gibt viele Dinge, die Sie tun können (zB Zugriff auf Arrays außerhalb der Grenzen), aber in Wirklichkeit, wenn diese Dinge gegen die Regeln der Sprache verstoßen, Sie werden undefined behavior auslösen.

Es hilft in der Tat auch nicht, dass der Compiler Sie nicht immer davor warnen wird.

Dies ist nur, wie die Sprache funktioniert, müssen Sie die meiste Zeit selbst vorsichtig sein, diese Regeln nicht zu verletzen.

0

Mit strcpy() kopiert die Anzahl der Zeichen, die Sie an das von Ihnen definierte Ziel senden möchten. Es prüft nicht auf die Grenzen Ihres Arrays. Es kopiert einfach weiter, bis es das ganze Wort kopiert hat.


Dies bedeutet, dass Sie es ohne einen Kompilierfehler tun dürfen. Dies ruft jedoch auf (siehe this link, um es zu verstehen), da Sie nicht sicher sein können, was außerhalb der Grenzen des zugewiesenen Speichers geschieht. In Ihrem Fall ist nichts Schlimmes passiert (eigentlich war das was Sie wollten), aber Sie können sich im Allgemeinen nicht sicher sein.

-1

Das Array, das Sie dynamisch zuweisen, Es wird von Heap-Speicher zugewiesen. Wie @Rudy Velthuis erwähnt hat, ist der Heap-Speicher in großen Blöcken aufgeteilt. Im normalen Szenario läuft Ihr Programm also gut. Aber bedenken Sie ein Szenario, in dem eine knappe Situation ist und der größte Teil Ihres Arbeitsspeichers Ihres Computers belegt ist. Zu diesem Zeitpunkt besteht eine hohe Wahrscheinlichkeit, dass Speicherabschnitte eines Prozesses im Heap neben dem Heap-Chunk liegen, der Ihrem Prozess zugeordnet ist.Wenn Sie die Situation noch probabilistischer machen, gehen Sie davon aus, dass Ihr Array am äußersten Ende des Heapspeichers zugewiesen wird. Wenn Sie dann über das Ende des zugewiesenen Speichers hinaus zugreifen, wird Ihr Programm auf den Heap anderer Programme zugreifen.In diesem Fall tritt OS ein, verweigert den Zugriff auf Ihr Programm und Ihr Programm stürzt ab.

Hoffe, es hilft Ihnen.

+0

Downvoter, Geben Sie Grund zur Abstimmung. –

+0

Ihr einmal erstelltes Programm verhält sich in einer engen oder nicht dichten Speichersituation genau gleich. – tofro

+0

@tofro, Ich habe ein hypothetisches Szenario beschrieben. Außerdem habe ich persönlich das gleiche erlebt. Programm kompiliert mit Turbo-Compiles, Speicherzugriff über Grenzen hinaus, abgestürzt manchmal und manchmal lief es gut. Ich wünschte, ich könnte Ihnen diese ausführbare Datei präsentieren. –

Verwandte Themen