【问题标题】:XOR Doubly Linked ListXOR 双向链表
【发布时间】:2019-06-03 04:48:10
【问题描述】:

所以我正在尝试创建一个 XOR 双链表作为练习的一部分,但我的 removeFirst() 函数不断出现分段错误。我无法弄清楚出了什么问题,有人有线索吗?

这是一个节点的样子:

class Node{

public:
    int data;
    Node *XOR;

};

我正在使用这个函数来计算异或:

Node* returnXOR(Node *a, Node *b){
    return (Node*)((uintptr_t) (a) ^ (uintptr_t) (b));
}

这是我的 XOR 双向链表类:

class XORDLL{

public:
Node *head;

XORDLL(){
    head = NULL;
}

void addFirst(int data){
    // Make a newNode pointer
    Node *newNode = new Node;

    // Set the variables
    newNode->data = data;
    newNode->XOR = returnXOR(head, NULL);   

    // If the head is not empty set the XOR of the head to the next XOR the newNode
    if(head != NULL){
        head->XOR = returnXOR(newNode, returnXOR(head->XOR, NULL));
    }   

    // Set the newNode to the head 
    head = newNode;
}

void removeFirst(){
    // If head is equal to NULL, do nothing
    if(head == NULL){
        return;
    }
    // Store current head
    Node *tmp = head;

    // Set head equal to the next address
    head = returnXOR(tmp->XOR, NULL);
    head->XOR = returnXOR(tmp->XOR, tmp);


    // Delete tmp variable
    delete tmp;
}

void printList(){
    Node *current = head;
    Node *prev = NULL;
    Node *next;
    while(current != NULL){
        printf("%d ", current->data);
        next = returnXOR(current->XOR, prev);
        prev = current;
        current = next;           
    }
    printf("\n");
}
};

当我运行这段代码时:

int main(){
    XORDLL l;
    l.addFirst(1);
    l.addFirst(2);
    l.addFirst(3);
    l.printList();
    l.removeFirst();
    l.printList();
    return 0;
}

这是输出:

3 2 1 分段错误(核心转储)

【问题讨论】:

  • 你的returnXOR 函数获取两个现有Nodes 的原始内存地址,对这两个原始内存地址进行异或,并将结果转换为指向另一个Node 的指针。不幸的是,生成的内存地址是指向Node 的有效指针的实际机会微乎其微。因此你的崩溃。这就像在非洲沙漠中获取两个绿洲的地理经度和纬度,不包括经度/纬度或数字经度/纬度,前往新的坐标集,并期望在那里找到第三个绿洲。
  • 我也是这么想的,但是为什么我的 printList() 函数在使用相同的方法时可以正常工作。
  • 因为,如果您计算出数学,该代码总是最终访问两个有效节点,然后计算一个 NULL 值(第一个与 null 异或,与 0 异或,什么都不做;下一次迭代异或自身的内存地址,产生 NULL)。你在那里很幸运。顺便说一句,delete current, prev, next; 并没有按照你的想法去做。我重复一遍,它不会删除三个指针。看来spend a little bit more time reading a good C++ book是个好主意。
  • 感谢您提供的信息,我必须自己解决。
  • @JornvanderMaat Node *newNode = (Node*) malloc (sizeof(Node)); -- 你为什么在 C++ 程序中使用 malloc?该代码表现出未定义的行为,因为 Node 不是 POD 类型。您的代码不构造 Node 对象——在 C++ 中,operator new 用于动态构造类型。 malloc 所做的只是分配字节——它不构造对象。

标签: c++ data-structures doubly-linked-list


【解决方案1】:

deletemalloc'ed 数据。您需要使用free 代替它,或者使用new 代替malloc。 另一个错误是你错过了这一行:

          void removeFirst(){
          // If head is equal to NULL, do nothing
          if(head == NULL){
              return;
          }
          // Store current head
          Node *tmp = head;

          // Set head equal to the next address
          head = returnXOR(tmp->XOR, NULL);
          head->XOR = returnXOR(head->XOR, tmp); <<<<<<<<<<<<<<<<<< Here

          // Free tmp variable
          free(tmp);
      }

【讨论】:

  • 虽然这也是正确的,但这是显示代码的众多问题中最少的一个。
  • 所以我更改了代码以摆脱删除语句并免费使用,但我仍然得到相同的输出。
  • 修复了另一个错误:)
  • 首先不应该调用malloc,因为Node 数据类型是完全错误的。因此,您不应该鼓励使用free
  • 我会说也不应该打电话给new。但是当你处理低级异或指针时,我认为malloc 不是一个大问题,因为它不是真正的 C++,它只是 C。
猜你喜欢
  • 2019-09-02
  • 2014-09-15
  • 2015-10-12
  • 1970-01-01
  • 2013-11-15
  • 2015-03-24
  • 2015-04-04
  • 2021-11-18
相关资源
最近更新 更多