段。错误调整数组大小 C++
Seg. fault resizing array C++
我有一个优先级队列数组,其中填充了 "Jobs"(名称 + 优先级)。如果它已满,除了重新调整大小之外,我已经能够让所有与队列相关的工作。这是我认为导致分段错误的位,我一直无法弄清楚。
编辑:
这里还有一些可以编译的代码,我保留了其余的函数,以防它们有任何帮助。现在初始容量设置为 5,当您尝试将作业添加到完整列表时,它将使阵列容量加倍,并允许您在 SEG 之前添加更多作业。过错。
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
#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();
}
我认为当你++count
时,下一次使用count
将超出数组范围。
array[++count].setPriority(priority);
// SEGMENTATION FAULT HERE
array[count].setTaskName(value);
如果数组的容量是 5,而 count
是 4,那么您只是将 count
递增到 5,并试图访问越界的元素 5。
array = new Job[capacity];
for (int i = 0; i < count; i++) {
array[i] = oldArray[i];
}
假设 capacity
为 10,因此您有一个包含 10 个元素的数组,范围从元素 0 到 9。
count
告诉我们正在使用多少元素。
如果 count
恰好是 9
,那么当您将 count
递增 1 时,它现在是 10
。然后,当您标记为产生段错误的行出现时,您正在尝试访问元素 10
,在我们的示例中。长度为 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!
当然,该部分之后的所有内容都会导致相同的问题,因为您继续使用 array[count]
。
您的原始代码与@antiHUMAN 先前给出的答案完全相同。
您遇到的问题是混淆或错误地使用了基于 0 和基于 1 的概念。
您的第一个错误是使 capacity
成为一个从 0 开始的数字。 capacity
应该表示数组中项目的最大数量,因此你不应该从中减去 1。如果数组可以容纳 5 个项目,那么 capacity
应该是 5,而不是 4。
PriorityQueue::PriorityQueue() // constructor
{
count = 0;
capacity = INITIAL_CAPACITY; // this remains 1-based.
array = new Job[INITIAL_CAPACITY];
}
或使用初始化列表:
PriorityQueue::PriorityQueue() : count(0),
capacity(INITIAL_CAPACITY),
array(new Job[INITIAL_CAPACITY]) {}
您的情况下从 0 开始的数字应该是 count
,而不是 capacity
。鉴于此,由于 count
是基于 0 的,而 capacity
是基于 1 的,因此需要更改 enqueue
中的测试:
if(count + 1 == capacity){
expandCapacity();
cout << "\tList was full and has been expanded\n";
}
请注意,将 1 添加到计数中以说明 count
是基于 0 且 capacity
是基于 1 的事实。
我有一个优先级队列数组,其中填充了 "Jobs"(名称 + 优先级)。如果它已满,除了重新调整大小之外,我已经能够让所有与队列相关的工作。这是我认为导致分段错误的位,我一直无法弄清楚。
编辑:
这里还有一些可以编译的代码,我保留了其余的函数,以防它们有任何帮助。现在初始容量设置为 5,当您尝试将作业添加到完整列表时,它将使阵列容量加倍,并允许您在 SEG 之前添加更多作业。过错。
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
#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();
}
我认为当你++count
时,下一次使用count
将超出数组范围。
array[++count].setPriority(priority);
// SEGMENTATION FAULT HERE
array[count].setTaskName(value);
如果数组的容量是 5,而 count
是 4,那么您只是将 count
递增到 5,并试图访问越界的元素 5。
array = new Job[capacity];
for (int i = 0; i < count; i++) {
array[i] = oldArray[i];
}
假设 capacity
为 10,因此您有一个包含 10 个元素的数组,范围从元素 0 到 9。
count
告诉我们正在使用多少元素。
如果 count
恰好是 9
,那么当您将 count
递增 1 时,它现在是 10
。然后,当您标记为产生段错误的行出现时,您正在尝试访问元素 10
,在我们的示例中。长度为 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!
当然,该部分之后的所有内容都会导致相同的问题,因为您继续使用 array[count]
。
您的原始代码与@antiHUMAN 先前给出的答案完全相同。
您遇到的问题是混淆或错误地使用了基于 0 和基于 1 的概念。
您的第一个错误是使 capacity
成为一个从 0 开始的数字。 capacity
应该表示数组中项目的最大数量,因此你不应该从中减去 1。如果数组可以容纳 5 个项目,那么 capacity
应该是 5,而不是 4。
PriorityQueue::PriorityQueue() // constructor
{
count = 0;
capacity = INITIAL_CAPACITY; // this remains 1-based.
array = new Job[INITIAL_CAPACITY];
}
或使用初始化列表:
PriorityQueue::PriorityQueue() : count(0),
capacity(INITIAL_CAPACITY),
array(new Job[INITIAL_CAPACITY]) {}
您的情况下从 0 开始的数字应该是 count
,而不是 capacity
。鉴于此,由于 count
是基于 0 的,而 capacity
是基于 1 的,因此需要更改 enqueue
中的测试:
if(count + 1 == capacity){
expandCapacity();
cout << "\tList was full and has been expanded\n";
}
请注意,将 1 添加到计数中以说明 count
是基于 0 且 capacity
是基于 1 的事实。