2 Stimmen

Verwendung von XOR zur Implementierung einer doppelt verketteten Liste mit einem Zeiger pro Knoten

Ich habe Probleme mit XOR doppelt verknüpfen Liste, die einen Zeiger hat, die NEXT und PREV Zeiger von Knoten enthalten muss. Ich muss xor Adresse von Zeigern, dies zu tun, aber ich kann nicht. Ich kann eine Speicheradresse zuweisen, die aus zwei Adressen XORed, aber ich kann nicht Wert auf seine Adresse (dies hat Segmentation Fault Fehler):

int main(){
    int* ptr = new int;
    int *ptr2 = new int;
    ptr2 = (int*)((unsigned long)ptr ^ (unsigned long)ptr2);
    *ptr2= 5;        /here has segmentation fault
    cout <<*ptr2;    
    return 0;

Warum hat dieser Code einen Fehler? Wie kann ich ihn beheben?


danke für Ihre Antwort, aber ich kann meine Idee nicht übertragen, ich sage meine Frage mit anderen Worten: Normalerweise haben wir einen Zeiger, dem wir den Speicherplatz zuweisen, indem wir " neu "Diese Adresse, die für unseren Zeiger reserviert ist, wird durch das Betriebssystem bestimmt, richtig? Zum Beispiel ist die Adresse, auf die der Zeiger zeigt, 0x8f3400b (dies ist der Ort, an dem der Speicher frei ist, der reserviert werden kann) Ich möchte das manuell tun, indem ich die Adresse nicht mit neu Schlüsselwort wie dieser Code:

int* ptr1 = (int*) 0x2355;
int* ptr2 = (int*) 0x23ff;

Jetzt weiß ich nicht, die Adresse 0x2355 und 0x23ff kann reserviert werden oder nicht? dann entscheide ich, dass " neu "Diese Zeiger werden mit XOR verknüpft (siehe unten):

int* ptr1 = new int     //ptr1 is now manage by OS
int* ptr2 = new int     //like ptr1 ...

dann möchte ich XORing diese Zeiger und machen einen neuen Raum, um einen Knoten anhängen, die der dritte Knoten ist, aber ich kippe die Adressierung der es korrekt ist, aber wenn ich es bewerten wollen Segmentierung Fehler aufgetreten:

int* ptr1 = new int;    // for example the address is X
int* ptr2 = new int;    // for example the address is Y
int* ptr3 = (int*)((unsigned long)ptr1 ^ (unsigned long)ptr2);    //the final address is X^Y

Wie kann ich das korrigieren? Ich weiß nicht, wie man intptr_t und andere bitte helfen Sie mir danke

9voto

Keith Thompson Punkte 240701

Es gibt einen wirklich hässlichen Trick, mit dem man (wenn er funktioniert) eine doppelt verkettete Liste mit nur einem Zeiger pro Knoten implementieren kann. Wie Sie sagen, erfordert es xor'ing Zeigerwerte.

Dieser Wikipedia-Artikel erörtert.

Das ist fast immer eine wirklich schlechte Idee. Die Sprache garantiert nicht, dass es überhaupt funktionieren wird.

Wenn Sie dies tun müssen, wandeln Sie die Zeigerwerte in uintptr_t o intptr_t (die Existenz dieser Typen ist nicht einmal garantiert, aber wahrscheinlich), deklariert in <stdint.h> o <cstdint> .

Das Ergebnis des Xor'ing zweier Zeigerwerte ist no ein gültiger Zeiger sein, und jeder Versuch, ihn als solchen zu verwenden, wird Ihnen ins Gesicht fliegen (wenn Sie Glück haben). Die einzige Möglichkeit, nach einer solchen Operation einen gültigen Zeiger zurückzubekommen, besteht darin, sie rückgängig zu machen, um den ursprünglichen Zeigerwert zu erhalten. Es ist nicht überraschend, dass Ihr *ptr2 = 5; verursacht einen Segmentierungsfehler.

Wenn Sie dies nur als Übung machen, um zu sehen, ob Sie es zum Laufen bringen können, haben Sie auf jeden Fall Spaß dabei.

Wenn Sie glauben, dass Sie einen praktischen Bedarf dafür haben, du nicht . Wenn Sie eine doppelt verkettete Liste wollen, brauchen Sie nur zwei Zeiger pro Knoten. Oder, besser noch, da Sie in C++ programmieren, verwenden Sie eine der Containerklassen der Standardbibliothek.

0voto

Tu das nie

Wenn Sie unbedingt Zeiger auf einen Integer-Typ casten wollen, verwenden Sie intptr_t mindestens (bereitgestellt von <cstdint> o <stdint.h> Header-Datei).

Warum wollen Sie xoder Zeigern? Das ist ein hässlicher Trick! Er deaktiviert gewissermaßen die Compiler-Optimierungen.

0voto

Prabhakaran Punkte 23

Unter Verwendung von Turbo C Version 3.0 haben wir eine doppelt verkettete Liste mit einem Zeiger implementiert, die die Vorteile von XOR nutzt. Übergeben Sie Ihre Kommentare.... C' das Änderungsteam von FINDMIND.

/* Code developed by 'C' The Change Team of FINDMIND
   Prabhakaran D, Vaishnavi N K, N N Priya, guided by
   Mr.Sridhar Arumugaswamy */

#include <stdio.h>
#include <conio.h>

struct Node {
   int data;
   unsigned int next;
}*start, *end, *newNode;

typedef struct Node NODE;

int menu(){
   int choice;
   clrscr();
   printf("1.Add\n2.Display\n3.Exit\n");
   scanf("%d", &choice );
   fflush(stdin);
   return choice;
}

void add() {
   clrscr();
   newNode = ( NODE * ) malloc ( sizeof( NODE ) );
   newNode -> next = 0;
   printf("Enter the data to enter :");
   scanf("%d", &(newNode -> data) );
   fflush(stdin);
   if( start == NULL ) {
      start = end = newNode;
   } else {
      newNode -> next = (unsigned int)end ^ 0;
      end -> next = ( end -> next ^ 0 ) ^ ( unsigned int)newNode;
      end = newNode;
   }
}

void display() {
   NODE *temp, *curr, *prev;
   prev = curr = temp = NULL;
   clrscr();
   for ( curr = start; curr != end ; temp = prev ,\
   prev = curr , curr = ( NODE * ) ( curr -> next ^ (unsigned int)temp ) )
      printf("%d\n", curr -> data );
   printf("%d\n", curr -> data );
   getch();
}

void main() {
   int choice;
   choice = menu();
   do {
      switch( choice ) {
     case 1: add();
         break;
     case 2: display();
         break;
     case 3: printf("\n\nBye!!!");
         break;
     default: printf("Bug dude!!!");
      }
      choice = menu();
   } while(choice != 3);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X