简体   繁体   English

段 故障调整数组C ++的大小

[英]Seg. fault resizing array C++

I have a priority queue array that is filled with "Jobs" (name + priority). 我有一个优先级队列数组,其中填充有“作业”(名称+优先级)。 I've been able to get everything queue related working aside from re sizing if it is full. 除了调整大小是否已满以外,我已经能够使所有与队列相关的工作正常进行。 Here is the bits that I think are causing a segmentation fault that I haven't been able to figure out. 我认为这是导致细分错误的原因,但我无法弄清楚。

EDIT: 编辑:

Here is a bit more code that will compile, I left in the rest of the functions in case those might help in any way. 这里还有更多可编译的代码,我留给其余函数,以防它们可能以任何方式提供帮助。 Right now the initial capacity is set to 5, when you try to add a job to the full list it will double the capacity of the array and allow you to add a couple more jobs before a SEG. 现在,初始容量设置为5,当您尝试将作业添加到完整列表时,它将使阵列的容量增加一倍,并允许您在SEG之前添加几个作业。 fault. 故障。

pq.h pq.h

#ifndef PQ_H
#define PQ_H
#include "interface.h"
#include <string>
using namespace std;

class Job {
    public:
        int getPriority();
        string getTaskName();
        void setPriority(int val);
        void setTaskName(string tname);
        Job();
    private:
        int priority;
        string taskName;
};

class PriorityQueue {

    public:
        PriorityQueue();
        ~PriorityQueue();
        int size();
        bool isEmpty();
        void clear();
        void enqueue(string value, int priority);
        string dequeue();
        string peek();
        int peekPriority();
        PriorityQueue(const PriorityQueue & src);
        PriorityQueue & operator=(const PriorityQueue & src);

    private:
        static const int INITIAL_CAPACITY = 5;  
        Job *array;
        int count;
        int capacity;

    void expandCapacity() {
        Job *oldArray = array;
        capacity *= 2;
        array = new Job[capacity];
        for (int i = 0; i < count; i++) {
            array[i] = oldArray[i];
        }
        delete[] oldArray;
    }
};

#endif

pq.cpp pq.cpp

#include <iostream>
#include <cstring>
using namespace std;
//#include "job.h"
#include "pq.h"

Job::Job() // Constructor
 {
    priority= 0;
    taskName = "There are no items in the list.";
}

int Job::getPriority(){ // returns the prority of the job
    return priority;
}
string Job::getTaskName(){ // returns the name of the job
    return taskName;
}
void Job::setPriority(int val){ // sets the priority of a newly created job
    priority = val;
}
void Job::setTaskName(string tname){ // sets the name of a new job
    taskName = tname;
}

PriorityQueue::PriorityQueue() // constructor
    {
        count = 0;
        capacity = INITIAL_CAPACITY - 1;
        array = new Job[INITIAL_CAPACITY];
        }

PriorityQueue::~PriorityQueue() { // destructor
   delete [] array;

}

int PriorityQueue::size() { // returns the number of jobs in the queue
   return count;  
}

bool PriorityQueue::isEmpty() { // returns true if queue is empty
   if (count != 0){
       return false;
   }else{
   return true;
   }
}

void PriorityQueue::clear() { // clears queue of all jobs
   count = 0;
   // need to make it remove and delete the items
}

void PriorityQueue::enqueue(string value, int priority) { 
   // tests size to see if Queue is a max capacity
   if(count == capacity){
       expandCapacity();
       cout << "\tList was full and has been expanded\n";
   }
   array[++count].setPriority(priority);
   array[count].setTaskName(value);

   // upheap operations
   Job v = array[count];
   int tempcount = count;
   while (array[tempcount/2].getPriority() >= v.getPriority()){
       array[tempcount] = array[tempcount/2];
       tempcount = tempcount/2;
   array[tempcount] = v;
   }

}
string PriorityQueue::dequeue() { 
    // removes the job with the highest priority from the queue and returns the name

    if(this->isEmpty()){ // make sure the queue isnt empty
        string empty = "The queue is empty";
        return empty;   
    }else{
   Job remove = array[1];
   array[1] = array[count--];

   int j;
   Job v;
   int k = 1;
   v = array[k];
   while(k <= count/2){
       cout << "dequeuewhile"; //  test
       j = k + k;
       if(j < count && array[j].getPriority() > array[j+1].getPriority()){
           j++;
           cout << "dequeueloop if1"; // test
       }
       if(v.getPriority() <= array[j].getPriority()){
           cout << "dequeueloop if2"; //test
           break;
       }
       array[k] = array[j];
       k = j;
   }
   array[k] = v;

   return remove.getTaskName(); //  returns the name of the removed job
    }
}
string PriorityQueue::peek() { // returns the name of the highest priority job without removing it from the queue
    if(count == 0){
        return array[0].getTaskName();
    }
   return array[1].getTaskName();
}

int PriorityQueue::peekPriority() { // returns the priority from the highest priority job without removing it from the queue
        if(count == 0){
        cout << "\tThere are no items in the list.\n";
        return array[0].getPriority();
    }
   return array[1].getPriority();
}

I think that when you do ++count , the next use of count will be out of bounds for the array. 我认为,当你做++count ,以备下次使用的count会出界对数组的。

array[++count].setPriority(priority);
// SEGMENTATION FAULT HERE
array[count].setTaskName(value); 

If the capacity of the array is 5, and count was 4, then you just incremented count to 5, and tried to access element 5, which is out-of-bounds. 如果数组的容量为5, count为4,则只需将count增加到5,然后尝试访问元素5(越界)。

 array = new Job[capacity];
 for (int i = 0; i < count; i++) {
     array[i] = oldArray[i];
 }

Lets assume capacity is 10, so you've got an array of 10 elements, ranging from elements 0 to 9. count tells us how many elements are being used. 让我们假设capacity为10,那么你有10个元素的数组,从元素0到9的count告诉我们有多少元素被使用。 If count happens to be 9 , then when you increment count by one, it is now 10 . 如果count恰好是9 ,那么当您将count增加1时,现在是10 Then, when line come you marked as producing segment fault comes, you're trying to access element 10 , in our example. 然后,当您标记为生产段故障的线路到达时,在本例中,您尝试访问元素10 There is no element 10 in an array of length 10 , so you're out of bounds. 长度为10的数组中没有元素10 ,所以您超出范围。

array[++count].setPriority(priority); // array[10], but last element is 9!
// SEGMENTATION FAULT HERE
array[count].setTaskName(value); // array[10], but last element is 9!

And, of course, everything after that part causes the same issue, as you keep using array[count] . 而且,当然,此部分之后的所有内容都会导致相同的问题,因为您继续使用array[count]

Your original code did exactly as the previous answer given by @antiHUMAN. 您的原始代码与@antiHUMAN给出的先前答案完全相同。

The problem you're having is mixing or erroneously using 0-based and 1-based concepts. 您遇到的问题是混合使用或错误使用基于0和1的概念。

Your first mistake is to make capacity a 0-based number. 您的第一个错误是将capacity设为从0开始的数字。 The capacity should denote the maximum number of items in an array, thus you should not be subtracting 1 from it. capacity应表示一个数组中的最大项目数,因此不应从中减去1。 If the array can hold 5 items, then capacity should be 5, not 4. 如果阵列可以容纳5个项目,则capacity应为5,而不是4。

PriorityQueue::PriorityQueue() // constructor
{
    count = 0;
    capacity = INITIAL_CAPACITY;  // this remains 1-based.
    array = new Job[INITIAL_CAPACITY];
}

or using the initializer-list: 或使用初始化列表:

PriorityQueue::PriorityQueue() : count(0), 
                                 capacity(INITIAL_CAPACITY), 
                                 array(new Job[INITIAL_CAPACITY]) {}

The 0-based number in your situation should be count , not capacity . 您所处情况的从0开始的数字应该是count ,而不是capacity Given that, since count is 0-based, and capacity is 1-based, your test in enqueue needs to be changed: 鉴于此,由于count是基于0的, capacity是基于1的,因此需要更改入enqueue测试:

   if(count + 1 == capacity){
        expandCapacity();
        cout << "\tList was full and has been expanded\n";
    }

Note that 1 is added to count to account for the fact that count is 0-based and capacity is 1 based. 请注意,计数增加了1,以说明count基于0且capacity基于1的事实。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM