微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

双端队列数组实现中的分段错误

如何解决双端队列数组实现中的分段错误

我正在尝试用C ++实现DeQue。我在调用insertFront函数时遇到了细分错误。我没有得到代码中的错误。请帮助我找出原因。这是代码

#include <iostream>

using namespace std;

#define MAX 100

class DeQueue {
    int arr[MAX];
    int front;
    int rear;
    int size;
    
public:
    DeQueue(int size){
        front = -1;
        rear = -1;
        this->size = size;
    }
    
    void insertFront(int n);
    void insertRear(int n);
    int deleteFront();
    int deleteRear();
    bool isEmpty();
    bool isFull();
    int getFront();
    int getRear();
};

bool DeQueue::isEmpty(){
    return (((front - 1) % size == rear) || (front == -1 && rear == -1));
}

bool DeQueue::isFull(){
    return ((front - 2) % size == rear);
}

void DeQueue::insertFront(int n){
    if(isFull()){
        cout << "Stack overflow!" << endl;
        return;
    }

    if(front == -1 && rear == -1)
        front = rear = size - 1;
    else
        front = (front - 1) % size;
    
    arr[front] = n;
}

void DeQueue::insertRear(int n){
    if(isFull()){
        cout << "Stack overflow!" << endl;
        return;
    }

    if(front == -1 && rear == -1)
        front = rear = 0;
    else
        rear = (rear + 1) % size;

    arr[rear] = n;
}

int DeQueue::deleteFront(){
    if(isEmpty()){
        cout << "Stack underflow!" << endl;
        return 0;
    }
    
    int temp = arr[front];
    front = (front + 1) % size;
    return temp;
}

int DeQueue::deleteRear(){
    if(isEmpty()){
        cout << "Stack underflow!" << endl;
        return 0;
    }

    int temp = arr[rear];
    rear = (rear - 1) % size;
    return temp;
}

int DeQueue::getFront(){
    if(isEmpty()){
        cout << "Stack underflow!" << endl;
        return 0;
    }

    return arr[front];
}

int DeQueue::getRear(){
    if(isEmpty()){
        cout << "Stack underflow!" << endl;
        return 0;
    }

    return arr[rear];
}

int main() {
    
    DeQueue dq(5); 
    cout << "Insert element at rear end  : 5 \n"; 
    dq.insertRear(5); 
  
    cout << "insert element at rear end : 10 \n"; 
    dq.insertRear(10); 
  
    cout << "get rear element " << " " << dq.getRear() << endl; 
  
    dq.deleteRear(); 
    cout << "After delete rear element new rear" << " become " << dq.getRear() << endl;
  
    cout << "inserting element at front end \n"; 
    dq.insertFront(15); 
  
    cout << "get front element " << " " << dq.getFront() << endl; 
  
    dq.deleteFront(); 
  
    cout << "After delete front element new " << "front become " << dq.getFront() << endl; 
    return 0;
}

输出

Insert element at rear end  : 5 
insert element at rear end : 10 
get rear element  10
After delete rear element new rear become 5
/usr/bin/timeout: the monitored command dumped core
sh: line 1: 17584 Segmentation fault      /usr/bin/timeout 10s main

解决方法

您有一些严重的实施问题。 其中之一:

void DeQueue::insertFront(int n){
    if(isFull()){
        cout << "Stack overflow!" << endl;
        return;
    }

    if(front == -1 && rear == -1)    // <- This is definitely problem if rear != -1,as in your case 
        front = rear = size - 1;            
    else
        front = (front - 1) % size; // this is where you get on first insertFront() by rear != -1
    
    arr[front] = n;  // front < 0!! in your case because rear != -1
}

还要注意C ++中%运算符及其对mod的数学定义的差异:如果除数和除数具有不同的符号,则C ++中的%可以提供负值。

,
$ g++ -o stackoverflowasan stackoverflowasan.C -Wall -g -fsanitize=address
$ gdb ./stackoverflowasan
(gdb) catch syscall exit_group
(gdb) run
...
Insert element at rear end  : 5 
insert element at rear end : 10 
get rear element  10
After delete rear element new rear become 5
inserting element at front end 
=================================================================
==319319==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7fffffffcc8c at pc 0x00000040169a bp 0x7fffffffcc40 sp 0x7fffffffcc30
WRITE of size 4 at 0x7fffffffcc8c thread T0
    #0 0x401699 in DeQueue::insertFront(int) /home/jkratoch/t/stackoverflowasan.C:49
    #1 0x401ec7 in main /home/jkratoch/t/stackoverflowasan.C:121
    #2 0x7ffff70c6041 in __libc_start_main ../csu/libc-start.c:308
    #3 0x40115d in _start (/quad/home/jkratoch/t/stackoverflowasan+0x40115d)

Address 0x7fffffffcc8c is located in stack of thread T0 at offset 28 in frame
    #0 0x401d34 in main /home/jkratoch/t/stackoverflowasan.C:106
...

(gdb) frame 5
#5  0x000000000040169a in DeQueue::insertFront (this=0x7fffffffcc90,n=15) at stackoverflowasan.C:49
49      arr[front] = n;
(gdb) p front
$1 = -1
(gdb) p rear
$2 = 0

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。