[PYTHON] Segfo mit 16 Zeichen in C-Sprache

↓ Es scheint, dass es in letzter Zeit beliebt ist, Python mit Segmentierungsfehler zu löschen. Segfo mit Python in drei Zeilen Segfo mit Python in 2 Zeilen Segfo mit Python in einer Zeile Segfo mit 33 Zeichen in Python Segfo mit Python in einer Zeile ohne Verwendung von ctypes Segfo mit Rost in 5 Zeilen Nur das Thema (Python) auf C zu ändern, macht es langweilig, aber es ist das gleiche.

Code

Bestätigter Betrieb mit gcc 10.1.0 (Warnung erscheint)

*a;main(){*a=0;}
> gcc segf.c
segf.c:3:4:Warnung:Die Datendefinition hat keinen Typ oder keine Speicherklasse
    3 |    *a;main(){*a=0;}
      |    ^
segf.c:3:5:Warnung:Der Typ wird in der Deklaration von "a" zum Standard "int" angegeben.[-Wimplicit-int]
    3 |    *a;main(){*a=0;}
      |     ^
segf.c:3:7:Warnung:Machen Sie den Rückgabetyp zum Standard-Int.[-Wimplicit-int]
    3 |    *a;main(){*a=0;}
      |       ^~~~
> ./a.out
zsh: segmentation fault (core dumped)  ./a.out

** Achtung ** Derzeit beträgt die Mindestanzahl von Zeichen, die zum Segmentieren der C-Sprache verwendet werden können, 5 Zeichen. (Siehe Kommentare unten)

Kurzer Kommentar

Dies allein entspricht nicht den Artikelanforderungen von Qiita, daher werde ich es kurz erläutern. Der erste Code, der angezeigt wird, ist ↓.

int main(void) {
    int *a = 0;
    *a = 0;  //← Fall hier
    return 0;
}

Die C-Sprache hat ein Konzept, das als Zeiger bezeichnet wird und mit dem Sie auf jede Adresse im Speicher zugreifen können. Deklarieren Sie einen Zeiger mit dem Namen "a" bei "int * a = 0" und weisen Sie die Speicheradresse "0" zu. Wenn Sie in der zweiten Zeile einen Wert für "* a" zuweisen, wird auf eine Adresse [^ 1] zugegriffen, die tatsächlich nicht vorhanden ist, und es tritt eine CPU-Ausnahme auf.

Kurzcodierung

Kürzen wir nun den obigen Code. Erstens kann "return 0" gemäß der C-Sprachkonvention weggelassen werden. [^ 5] Auch der Rückgabetyp "int" kann aus Kompatibilitätsgründen weggelassen werden. (Wenn weggelassen, ist es implizit "int".) Außerdem funktioniert es, ohne das Argument "void" zu schreiben. Basierend auf diesen ist es wie folgt.

 main() {
    int *a = 0;
    *a = 0;  //← Fall hier
}

Hier kann die lokale Variable "a" als globale Variable definiert werden. Wenn Sie es als globale Variable definieren, wird es außerdem mit "0" initialisiert (es sei denn, es handelt sich um eine ganz besondere Umgebung), sodass keine Zuweisung für die Initialisierung erforderlich ist [^ 6].

int *a;
main() {
    *a = 0;  //← Fall hier
}

Außerdem kann der globale Variablentypbezeichner "int" weggelassen werden. Dies ist der Code am Anfang.

Bonus. Existiert die Adresse "* (0p00000000)" wirklich?

In einem klassischen Computer ist Speicher ein Gerät, das viele Informationen speichern kann. Um jedoch viele Informationen an den Speicher zu senden oder aus dem Speicher zu empfangen, sind intuitiv so viele Drähte erforderlich, wie die Anzahl der Informationen, die Sie senden und empfangen möchten. In Bezug auf die Kosten ist es jedoch nicht möglich, viele dünne Drähte vorzubereiten, die der Betriebsgeschwindigkeit der CPU standhalten. Daher werden wir das Konzept der Speicheradresse einführen. Obwohl die Anzahl der Informationen, die gleichzeitig gelesen und geschrieben werden können (1Byte genannt) [^ 2], gering ist, können viele Informationen durch Ändern der Speicheradresse im Speicher gespeichert werden.

Auf diese Weise ist das Konzept der Speicheradresse im Zeitalter großer Speicherkapazität unverzichtbar, aber da es durch eine positive ganze Zahl beginnend mit "0" dargestellt wird, existiert die Adresse "0" tatsächlich. .. Der Grund, warum der Segmentierungsfehler aufgetreten ist, liegt in der vom Betriebssystem verwendeten CPU-Funktion Paging.

Speicheradressen sind auf einem Computer eindeutig. Sofern nicht anders angegeben, besitzen mehrere Prozesse in einem Multitasking-Betriebssystem denselben Speicheradressraum. In diesem Fall müssen Sie beim Zugriff auf den Speicher darauf achten, nicht versehentlich auf den von anderen Prozessen verwendeten Speicher zuzugreifen. Durch Paging werden diese Unannehmlichkeiten beseitigt, sodass jeder Prozess seinen eigenen virtuellen Adressraum besitzt. Zu diesem Zeitpunkt verwaltet das Betriebssystem eine Tabelle, die zwischen dem virtuellen Adressraum [^ 3] und dem physischen (Speicher-) Adressraum konvertiert.

Daher sollte der Prozess auf alle vorhandenen Adressen zugreifen können. Dies ist jedoch in der Realität nicht der Fall, und das Betriebssystem nutzt auch den virtuellen Adressraum. Es begrenzt den Speicherbereich, der dem Programm zur Verfügung steht. Diese Art der Aufteilung des virtuellen Adressraums wird als Speicherzuordnung bezeichnet. Wie in [diesem Artikel] angegeben (https://qiita.com/akachochin/items/8d7d46a5f51bd230abc2), wird der Bereich um die Adresse 0 nicht verwendet (die entsprechende Adresse des physischen Speichers wird nicht zugewiesen) Ein Segmentierungsfehler tritt auf. [^ 4]

abschließend

Ich habe ungefähr 20 Minuten gebraucht, um es leicht zu schreiben. Ich hätte es schreiben sollen.

[^ 1]: Siehe unten. [^ 2]: Tatsächlich können 64 Bit gleichzeitig in jedes Speichermodul geschrieben werden. Darüber hinaus kann mithilfe von Technologien wie DMA mit hoher Geschwindigkeit auf den Speicher zugegriffen werden. [^ 3]: und linearer Adressraum [^ 4]: Es hängt davon ab, wie das Betriebssystem implementiert ist. Abhängig vom Betriebssystem tritt außerdem eine weitere CPU-Ausnahme auf. [^ 5]: Viele Leute denken fälschlicherweise, dass das Weglassen von "return 0;" ein Fehler ist. [^ 6]: Es ist in Ordnung, wenn Sie es nicht initialisieren, da es nur Segfo verursacht.

Recommended Posts

Segfo mit 16 Zeichen in C-Sprache
Segfo mit 0 Zeichen mit gcc
Segfo Python mit 33 Zeichen
Heap-Sortierung in C-Sprache
Modultest mit mehreren Instanzen in C-Sprache
Realisieren Sie die Schnittstellenklasse in der Sprache C.
Schreiben der C-Sprache mit Sympy (Metaprogrammierung)
Linkliste (list_head / queue) in C-Sprache
Generieren Sie mit Python eine C-Sprache aus dem S-Ausdruck
Kommunizieren Sie mit I2C-Geräten unter Linux C.
So steuern Sie Multiprozesse ausschließlich in C-Sprache
Richten Sie einen UDP-Server in der Sprache C ein
Erstellen Sie ein Bild mit Zeichen mit Python (Japanisch)
Installieren Sie das C-sprachabhängige Modul von Python im Wheel-Format mit mehrstufigem Build
Verarbeiten Sie Signale in C-Sprache
Versuchen Sie, ein Python-Modul in C-Sprache zu erstellen
Behälterartig hergestellt mit C # 1
C / C ++ - Debugging mit gdb
Greifen Sie auf MongoDB in C zu
Versuchen Sie, Python mit pybind11 in ein C ++ - Programm einzubetten
Weiter Python in C-Sprache
[C-Sprachalgorithmus] Endianness
C-API in Python 3
Gehen Sie in die Sprache, um Teil 7 C in der Sprache GO zu sehen und sich daran zu erinnern
Greifen Sie auf das Feld C-Struktur mit dem in Go reservierten Namen zu.
Verhalten in jeder Sprache, wenn Collouts mit for wiederverwendet werden
Ich habe versucht, die Zeit und die Zeit der C-Sprache zu veranschaulichen
[C-Sprachalgorithmus] Blockbewegung
Erweitern Sie Python in C ++ (Boost.NumPy)
Verwenden von X11 mit ubuntu18.04 (C-Sprache)
100 Sprachverarbeitungsklopfen mit Python 2015
Betreiben Sie LibreOffice mit Python
Schaben mit Chromedriver in Python
Versuchen Sie Google Mock mit C.
Verwenden Sie reguläre Ausdrücke in C.
Umgang mit Sounds in Python
Scraping mit Selen in Python
Nachahmung von Pythons Numpy in C #
Binäre Suche in Python / C ++
Scraping mit Tor in Python
Kombiniert mit Ordnungszahl in Python
Hallo Welt in GO-Sprache
[C Sprache] readdir () vs readdir_r ()
Segfo Python in 2 Zeilen
Formatieren Sie die Sprachquelle C mit pycparser
C-Sprache ALDS1_4_A Lineare Suche
Minimaler Gesamtflächenbaum in C #
Einführung in die in C Language Part 1 Server Edition erlernte Socket-API
C> Zeichenfolgenoperation> Implementierung zum Einfügen von char [] mit der angegebenen Ziffer
Dockerfile mit den notwendigen Bibliotheken für die Verarbeitung natürlicher Sprache mit Python
Verwenden wir das Entwurfsmuster wie die Sprache C mit OSS design_pattern_for_c!
Schreiben Sie eine C-Sprach-Linkliste in einem objektorientierten Stil (mit Codevergleich zwischen Python und Java).