Verwenden Sie niemals eine Gleitkommavariable, um eine ganze Zahl zu speichern. Gleitkommavariablen führen ungefähre Berechnungen durch. Es würde in diesem Fall funktionieren, weil die Integer klein genug sind, aber um das zu wissen, braucht man intime Kenntnisse darüber, wie Gleitkommazahlen auf einer bestimmten Maschine/einem Compiler funktionieren und welcher Bereich von Ganzzahlen du verwendest. Außerdem ist es schwieriger, das Programm zu schreiben, und das Programm wäre langsamer.
C definiert einen Integer-Typ, der groß genug ist, um einen Zeiger zu speichern: uintptr_t
. Sie können einen Zeiger auf uintptr_t
und zurück werfen. Auf einem 32-Bit-Rechner ist.ein 32-Bit-Typ, so dass nur Werte von bis zu 2 -1 gespeichert werden können. Um eine Schleife auszudrücken, die den gesamten Bereich des Typs einschließlich des ersten und des letzten Werts abdeckt, können Sie keine gewöhnliche for-Schleife mit einer inkrementierten Variable verwenden, da die Endbedingung einen Wert des Schleifenindex erfordert, der außerhalb des Bereichs liegt. Wenn Sie naiv
schreiben
uintptr_t i;
for (i = 0; i <= UINTPTR_MAX; i++) {
unsigned char *temp = (unsigned char *)i;
// ...
}
dann erhalten Sie eine Endlosschleife, weil nach der Iteration mit i
gleich UINTPTR_MAX
, laufen i++
wickelt den Wert von i
auf 0. Die Tatsache, dass die Schleife auch unendlich gesehen werden kann, in ein einfacherer logischer Weg: Die Bedingung i <= UINTPTR_MAX
ist immer wahr, da alle Werte des Typs kleiner oder gleich dem Maximum sind.
Sie können dies beheben, indem Sie den Test nahe am Ende der Schleife platzieren, bevor Sie die Variable inkrementieren.
i = 0;
do {
unsigned char *temp = (unsigned char *)i;
// ...
if (i == UINTPTR_MAX) break;
i++;
} while (1);
Beachten Sie, dass die Erforschung von 4GB auf diese Weise extrem langsam sein wird, wenn Sie es sogar tun können. Sie erhalten einen Segmentierungsfehler, wenn Sie versuchen, auf eine Adresse zuzugreifen, die nicht zugeordnet ist. Sie können den segfault mit einem Signal-Handler behandeln, aber das ist schwierig und langsam. Was du versuchst, mag vielleicht nicht das sein, was dein Lehrer erwartet, aber es macht keinen praktischen Sinn.
Um den Speicher eines Prozesses unter Linux zu untersuchen, lesen Sie /proc/self/maps
, um seine Speicherzuordnungen zu ermitteln. Ein Beispielcode in Python finden Sie in my answer on Unix.SE.
Beachten Sie auch, dass wenn Sie nach einem Muster suchen, Sie die Länge des gesamten Musters berücksichtigen müssen, eine Byte-für-Byte-Suche nicht die ganze Arbeit erledigt.
Kannst du 'uint32_t' stattdessen verwenden? –
Sie können ein 'long' oder sogar ein' long long' verwenden. – DyZ
Außerdem erhalten Sie fast sofort eine Zugriffsverletzung (aka "segfault"), da nicht alle Speicheradressen zugänglich sind. ;) –