Um Ihnen ein besseres Verständnis dafür zu geben, warum dies geschieht, möchte ich die Antwort von @ r-samuel-klatchko etwas näher erläutern.
Wenn Sie anrufen malloc, ist das, was wirklich passiert, etwas komplizierter, als Ihnen nur einen Teil des Gedächtnisses zum Spielen zu geben. Unter der Haube werden mallocauch einige Haushaltsinformationen über den Speicher gespeichert, den Sie erhalten haben (vor allem über die Größe), sodass er beim Anrufen beispielsweise freeweiß, wie viel Speicher freigegeben werden muss. Diese Informationen werden normalerweise direkt vor dem Speicherort gespeichert, den Sie von erhalten haben malloc. Ausführlichere Informationen finden Sie im Internet ™ , aber die (sehr) Grundidee ist ungefähr so:
+------+-------------------------------------------------+
+ size | malloc'd memory +
+------+-------------------------------------------------+
^-- location in pointer returned by malloc
Darauf aufbauend (und die Dinge stark vereinfachend) muss beim Aufrufen mallocein Zeiger auf den nächsten verfügbaren Teil des Speichers abgerufen werden. Eine sehr einfache Möglichkeit, dies zu tun, besteht darin, das zuvor verschenkte Speicherbit zu betrachten und die sizeBytes im Speicher weiter nach unten (oder oben) zu verschieben. Mit dieser Implementierung, beenden Sie mit Ihrem Gedächtnis auf etwas so aussehen , nachdem die Zuweisung p1, p2und p3:
+------+----------------+------+--------------------+------+----------+
+ size | | size | | size | +
+------+----------------+------+--------------------+------+----------+
^- p1 ^- p2 ^- p3
Was verursacht Ihren Fehler?
Stellen Sie sich vor, Ihr Code schreibt fälschlicherweise über die von Ihnen zugewiesene Speichermenge hinaus (entweder weil Sie weniger zugewiesen haben, als Sie als Problem benötigt haben, oder weil Sie irgendwo in Ihrem Code die falschen Randbedingungen verwenden). Sagen Sie den Code schreibt so viele Daten , p2dass es beginnt zu überschreiben , was in ist p3‚s sizeFeld. Wenn Sie jetzt das nächste Mal anrufen malloc, wird der zuletzt zurückgegebene Speicherort angezeigt, das Größenfeld angezeigt, der p3 + sizeSpeicherplatz verschoben und von dort aus mit der Zuweisung von Speicher begonnen. Da Ihr Code jedoch überschrieben sizewurde, befindet sich dieser Speicherort nicht mehr hinter dem zuvor zugewiesenen Speicher.
Unnötig zu sagen, dass dies Chaos zerstören kann! Die Implementierer von mallochaben daher eine Reihe von "Behauptungen" oder Überprüfungen abgegeben, die versuchen, eine Reihe von Überprüfungen der geistigen Gesundheit durchzuführen, um dies (und andere Probleme) zu erkennen, wenn sie in Kürze eintreten. In Ihrem speziellen Fall werden diese Behauptungen verletzt und daher mallocabgebrochen, um Ihnen mitzuteilen, dass Ihr Code etwas tun würde, was er eigentlich nicht tun sollte.
Wie bereits erwähnt, handelt es sich um eine grobe Vereinfachung, die jedoch ausreicht, um den Punkt zu veranschaulichen. Die glibc-Implementierung von mallocumfasst mehr als 5.000 Zeilen, und es wurden umfangreiche Untersuchungen zum Aufbau guter dynamischer Speicherzuweisungsmechanismen durchgeführt, sodass es nicht möglich ist, alles in einer SO-Antwort abzudecken. Hoffentlich haben Sie dadurch einen Überblick darüber bekommen, was das Problem wirklich verursacht!