2016-04-11 44 views
0

"İşler" (ad + öncelik) ile doldurulmuş bir öncelik sırası dizim var. Tamamlandığında, yeniden boyutlandırmanın yanı sıra, her şeyle ilgili her şeyi sıraya koyabiliyorum. İşte benim anlayamadığım bir bölütleme hatasına neden olduğunu düşündüğüm bitler.Seg. hata yeniden boyutlandırma dizisi C++

DÜZENLEME: İşte

O herhangi bir şekilde yardımcı olabilecek durumda fonksiyonların geri kalanında sol derleyecek biraz daha koddur. Şu anda başlangıç ​​kapasitesi 5 olarak ayarlanmıştır, tam listeye bir iş eklemeyi denediğinizde, dizinin kapasitesini iki katına çıkaracak ve SEG'den önce birkaç tane daha iş eklemenize izin verecektir. hata.

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 Sana ++count yaptığınızda, count sonraki kullanım dizisi için sınırların dışında olacağını düşünüyorum

#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(); 
} 
+0

Lütfen bir [mcve] yazınız. Şu anda olduğu gibi, 'expandCapacity' değerinizde 'new [] 'çağrılmadan önce üye değişkenlerini (' kapasite') değiştirdiğinizde birkaç kusur vardır. Yeni [] 'bir istisna atarsa,' PriorityQueue 'nesnesiniz bozulur. Diğer konu 'PriorityQueue 'sınıfınızın 3 kuralına uymamasıdır. Programınızın herhangi bir yerinde bir' PriorityQueue' kopyası yapılmışsa, davranış tanımlanmamıştır. Neden sadece 'Job * array' yerine std :: vector dizisini kullanmıyoruz? – PaulMcKenzie

+0

Örnekle alabildiğim en iyisini yaptım, gerçekten neyin yanlış gittiğinden emin değilim. Kapasite değişir, böylece eski olanı değiştirmek için 2x boyutunda yeni bir dizi yapılır. Bunun için vektörleri kullanamıyorum. – Drakorex

+0

'expandCapacity' çağrılmadan önce belleği bozabilirdiniz. Gerçekten belirtildiği gibi yapmalı ve [mcve] yazmalısınız. – PaulMcKenzie

cevap

0

Orijinal kodunuz, @antiHUMAN tarafından verilen önceki yanıtın aynısıydı.

Yapmakta olduğunuz sorun, 0 tabanlı ve 1 tabanlı kavramları kullanarak karıştırmak veya hatalı olarak kullanmaktır.

İlk hatanınız capacity 0 tabanlı bir sayıdır. capacity, bir dizideki öğelerin maksimum sayısını belirtmelidir, bu nedenle sizden 1 çıkarmamalısınız. Dizi 5 öğe tutabilir, sonra capacity, 5 olmalıdır değil 4.

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

veya başlatıcı-listesini kullanarak:

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

senin durumundaki 0 ​​tabanlı sayı olmalıdır count, capacity değil.count beri 0 tabanlı olduğundan göz önüne alındığında, ve capacity 1 tabanlı, enqueue yılında test değiştirilmesi gerekir ise: count 0- olduğu gerçeğini hesaba saymak 1 eklenir

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

Not olduğunu tabanlı ve capacity 1 tabanlı.

+0

Yardımınız için bir demet, 'if (count + 1 == capacity)' işlevlerini kullanarak teşekkürler, ancak dizinin gerekli olandan daha kısa sürede genişlemesine neden oluyor gibi görünüyor.'InitialCapacity = 2' ise, dizi saniyeden önce yerine ilk girdiden önce genişler. – Drakorex

+0

Not: Dizinize bir öğe eklediğinizde, hiçbir zaman öğe 0 'ı dolduramayacağınızı unutmayın.' Array [++ count] .setPriority (priority); '-' count' 1'e artırılır, yani dizi [ 0] 'asla nüfuslu veya değiştirilemez. Bu yine 0 temelli, 1 temelli bir sorundur, 'kapasite' ne anlama gelir? (Madde 0 hariç her şey veya dahil edilenler). – PaulMcKenzie

1

.

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

dizinin kapasitesi 5 ise

ve count o zaman sadece 5'e count artırılır ve out-of-sınırları olan eleman 5, erişmeye çalıştı, 4 oldu.

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

capacity 10 olduğunu varsayalım, bu nedenle elementlerden 0 9. count arasında değişen 10 elemanlardan oluşan bir dizi var kullanıldığını kaç tane öğenin söyler ettik. count, 9 olduğunda, count değerini bir artırdığınızda, artık 10. Ardından, üretim segmenti arızası geldiğinde satır olarak işaretlendiğinde, örneğimizde 10 elemanına erişmeye çalışıyorsunuz. 10 öğesinde 10 uzunluğunda bir öğe yok, bu nedenle sınırların dışındasınız. Eğer array[count] kullanmaya devam olarak

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! 

Ve tabii ki, o kısmı sonra her şey aynı sorunu neden olur.

+0

Sayım, içindeki veri ile en yüksek endeksi takip eder, bu yüzden elden önce arttırmak sadece bir sonraki önceliği nereye yerleştireceğinizi söyler, sonra adı. Ayrıca, bundan önceki kapasiteyi kontrol eder ve iki katına çıkarır. Kapasiteyi artırmaya çalıştıktan sonra sadece hatayı alıyorum. – Drakorex

+0

@Drakorex Neyin sayıldığını bilmiyoruz. Gönderdiğiniz kodla (şimdiye kadar) herhangi bir şey olabilir. – PaulMcKenzie

+0

@Drakorex Sayı == kapasite olup olmadığını görmek için bir kontrol yaparsınız, değil mi? Anladığım kadarıyla, "kapasite" dizinin uzunluğudur. Eğer "sayım", kapasiteden sadece bir tanesi ise, * sonra * sayımın == kapasitesini kontrol edip etmediğini (kapasiteyi arttırmak) kontrol ederseniz, "sayma" değerini artırırsınız, böylece * * kapasiteye eşittir. Yani, bana göründüğü gibi, eğer dizi uzunluğu 5 ise, o zaman element 5'e erişmeye çalışıyorsunuzdur. Fakat 5 uzunluğunda bir eleman 5 yoktur. Son eleman eleman 4'tür. Burada aptal olmak. :/ – antiHUMAN