2012-04-12 17 views
0

Ich habe ein Problem beim Zuweisen von Zeigern zu einem Array von Zeigern in meinem Programm. Ich habe es so eingerichtet, dass die Funktion einen Zeiger als Argument akzeptiert, und ich habe versucht, diesen Zeiger auf einen Index des Arrays zuzuweisen. Es kompiliert gut, aber es läuft nicht, ich bekomme einen segfault.Array von Zeigern auf eine abstrakte Klasse

Der Fehler kommt von EventHeap :: push, die erste Zeile in der Funktion.

Sie haben irgendwelche Ideen?

Ich schätze die Hilfe.

Edit: Ich werde das spezifische Problem rechts unten schreiben, aber ich werde nur den Code für den Fall, darunter verlassen: D

Die segfault tritt in der Push-Funktion, erste Zeile.

void ModemSimV2::nextCall(int delta){ 
    static int nextCallTime = 0; 
    static int userNum = 0; 

    Event *e; 
    e = new Dialin(userNum++, nextCallTime); 
    eventSet->push(e); 
    nextCallTime += delta; 
} 


//push function takes a pointer to an Event and puts into the array 
void EventHeap::push(Event *e) { 

    array[size] = e; 
    reIndex(size); 
    size++; 
} 

Quelle:

// ModemSimV2.cpp 
// 
// @author David Harrigan 
//   dtk24 
// 
// 4/10/2012 
// 
#include "ModemSimV2.h" 
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//++++++++++++++++++++++++++ ModemSimV2 +++++++++++++++++++++++++++ 

// Constructor for ModemSim. 
ModemSimV2::ModemSimV2(int modems, double avgLen, int callIntrvl) 
: freeModems(modems), avgCallLen(avgLen), 
freqOfCalls(callIntrvl), r((int) time(0)) 
{ 
    nextCall(freqOfCalls); // Schedule first call 
} 

// Place a new DIAL_IN event into the event queue. 
// Then advance the time when next DIAL_IN event will occur. 
// In practice, we would use a random number to set the time. 
void ModemSimV2::nextCall(int delta){ 
    static int nextCallTime = 0; 
    static int userNum = 0; 

    Event *e; 
    e = new Dialin(userNum++, nextCallTime); 
    eventSet->push(e); 
    nextCallTime += delta; 
} 

// Run the simulation until stopping time occurs. 
void ModemSimV2::runSim(int stoppingTime){ 
    Event *e; 
    int i = 0; 
    while(! eventSet->empty()){ 
     e = eventSet->pop(); 
     if (e->getTime() > stoppingTime) 
      break; 

     if (e->process(*this)) 
      eventSet->push(e); 

     nextCall(freqOfCalls); 
     i++; 
    } 
} 
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//+++++++++++++++++++++++++++++ Event +++++++++++++++++++++++++++++ 

//Constructor for event 
Event::Event(){ 

} 

//copy constructor 
Event::Event(const Event &e) { 
    *this = e; 
} 

//virtual destructor 
Event::~Event() { 

} 

//operator overloads 
bool Event::operator > (const Event & rhs) const { 
    return time > rhs.time; 
} 

bool Event::operator < (const Event & rhs) const { 
    return time < rhs.time; 
} 

bool Event::operator <= (const Event & rhs) const { 
    return time < rhs.time; 
} 

bool Event::operator != (const Event & rhs) const { 
    return time != rhs.time; 
} 

//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//+++++++++++++++++++++++++++++ Dialin +++++++++++++++++++++++++++++ 

//inhereited constructor 
Dialin::Dialin (int name, int tm) 
: time(tm), who(name) { 
    return; 
} 

//copy constructor 
Dialin::Dialin (const Dialin &d) { 
    *this = d; 
} 

//destructor 
Dialin::~Dialin() { 

} 

//bool process - unfinished 
bool Dialin::process(ModemSimV2 &m) { 
    cout << "User " << who << " dials in at time " 
    << time << endl; 

    if(m.freeModems > 0) { 
     m.freeModems--; 
     int howLong = r.negExp(m.avgCallLen); 
     cout << " and connects for " << howLong << 
     " minutes " << endl; 
     time += howLong; 
     return true; 
    } 
    else { 
     cout << "but gets busy signal" << endl; 
     return false; 
    } 
} 

//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//++++++++++++++++++++++++++++ Hangup +++++++++++++++++++++++++++++ 

//inhereited constructor 
Hangup::Hangup (int name, int tm) 
: time(tm), who(name) { 
    return; 
} 

//copy constructor 
Hangup::Hangup (const Hangup &h) { 
    *this = h; 
} 

//destructor 
Hangup::~Hangup () { 

} 

//bool process - unfinished 
bool Hangup::process(ModemSimV2 &m) { 

    m.freeModems++; 

    cout << "User " << who << " hangs up at time " 
    << time << endl; 

    return false; 

} 
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//++++++++++++++++++++++++++ EventHeap ++++++++++++++++++++++++++++ 

//EventHeap constructor 
EventHeap::EventHeap() { 

    array = new Event*[1]; 
    size = 0; 
} 

//constructor 
EventHeap::EventHeap(int numVals) { 

    array = new Event*[numVals]; 
    size = 0; 
} 

//push function takes a pointer to an Event and puts into the array 
void EventHeap::push(Event *e) { 

    array[size] = e; 
    reIndex(size); 
    size++; 
} 

//since this is a min-heap, it removes the smallest value in the array 
Event* EventHeap::pop() { 

    Event *e = array[0]; 
    array[0] = array[size - 1]; 
    size--; 
    if(!empty()) 
     buildHeap(0); 

    return e; 
} 

//builds the heap once popped, to reorder the array 
// 
void EventHeap::buildHeap(int index) { 

    int min; 

    if (getRight(index) >= size) { 
     if (getLeft(index) >= size) 
      return; 
     else 
      min = getLeft(index); 
    } 
    else { 
     if (array[getLeft(index)] <= array[getRight(index)]) 
      min = getLeft(index); 
     else 
      min = getRight(index); 
    } 
    if (array[index] != 0 && array[index] > array[min]) { 
     Event *temp(array[min]); 
     array[min] = array[index]; 
     array[index] = temp; 
     buildHeap(min); 
    } 
} 


//similar to buildHeap, but is called when a value is pushed to the array 
// 
void EventHeap::reIndex(int hole) { 

    while(array[hole] != NULL && array[hole] < array[getParent(hole)]) { 
     int pIndex = getParent(hole); 
     Event *temp(array[hole]); 
     array[hole] = array[pIndex]; 
     array[pIndex] = temp; 
     hole = pIndex; 
    } 
} 

//returns true if empty 
bool EventHeap::empty() const { 
    return (size == 0); 
} 

//returns the left child 
int EventHeap::getLeft(int index) const { 
    return (index * 2) + 1; 
} 

//returns the right child 
int EventHeap::getRight(int index) const { 
    return (index * 2) + 2; 
} 

//returns the parent 
int EventHeap::getParent(int index) const { 
    return (index - 1)/2; 
} 

Rubrik:

// ModemSimV2.h 
// 
// @author David Harrigan 
//   dtk24 
// 
// 4/10/2012 
// 

#ifndef MODEM_SIM_V2_H 
#define MODEM_SIM_V2_H 

#include <queue> 
#include <vector> 
#include <functional> // for greater() 
#include <climits>  // for INT_MAX 
#include <iostream> 
#include "random.h" 

using namespace std; 
//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//++++++++++++++++++++++++++ ModemSimV2 +++++++++++++++++++++++++++ 
class EventHeap; 

class ModemSimV2 { 

public: 
    ModemSimV2(int modems, double avgLen, int callIntrvl); 
    // Add a call to eventSet at the current time, 
    // and schedule one for delta in the future. 
    void nextCall(int delta); 

    // Run the simulation 
    void runSim(int stoppingTime);// = INT_MAX); 

    friend class Event; 
    friend class Dialin; 
    friend class Hangup; 

private: 
    Random r;      // A random source 
    EventHeap *eventSet;     // Pending events 

    // Basic parameters of the simulation 
    int freeModems;     // Number of modems unused 
    const double avgCallLen;  // Length of a call 
    const int freqOfCalls;   // Interval between calls 
}; 


//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//+++++++++++++++++++++++++++++ Event +++++++++++++++++++++++++++++ 

class Event{ 

protected: 
    int who;  // the number of the user 
    int time;  // when the event will occur 

    friend class ModemSimV2; 

    Random r; 

public: 
    Event(); 
    Event(const Event &e); 
    virtual ~Event(); 

    bool operator > (const Event & rhs) const; 
    bool operator < (const Event & rhs) const; 
    bool operator <= (const Event & rhs) const; 
    bool operator != (const Event & rhs) const; 

    int getTime() { return time; }; 

    virtual bool process(ModemSimV2 &m) = 0; 
}; 

//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//+++++++++++++++++++++++++++++ Dialin ++++++++++++++++++++++++++++ 
class Dialin : public Event { 
public: 
    Dialin(int name = 0, int tm = 0); 
    Dialin(const Dialin &d); 
    ~Dialin(); 

    virtual bool process(ModemSimV2 &m); 

private: 
    int who; 
    int time; 
}; 

//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//+++++++++++++++++++++++++++++ Hangup ++++++++++++++++++++++++++++ 
class Hangup : public Event { 
public: 
    Hangup(int name = 0, int tm = 0); 
    Hangup(const Hangup &h); 
    ~Hangup(); 

    virtual bool process(ModemSimV2 &m); 

private: 
    int who; 
    int time; 
}; 

//xvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvxvx 
//++++++++++++++++++++++++++ EventHeap ++++++++++++++++++++++++++++ 

class EventHeap{ 

public: 
    EventHeap(); 
    EventHeap(int numIndex); 

    bool empty() const; 
    const int & findMin() const; 

    void push(Event *x); 
    Event * pop(); 

private: 
    int size;   // Number of elements in heap 
    Event **array;   // The heap array 

    void buildHeap(int index); 
    void reIndex(int hole); 
    int getLeft(int index) const; 
    int getRight(int index)const; 
    int getParent(int index)const; 
}; 
#endif 
+0

Hört sich an, als hätten Sie das Problem auf ein wesentlich kleineres Maß als hier beschrieben reduziert ... können Sie die Frage aktualisieren, um das kleine, in sich abgeschlossene Beispiel wiederzugeben, damit wir leichter nach Problemen suchen können? – tmpearce

Antwort

1

Dies ist ein Hinweis:

e = new Dialin(userNum++, nextCallTime); 
eventSet->push(*e); 

Sie ein neues Objekt, Aufteilung und eine Kopie davon drücken.

Ein weiterer Hinweis:

// Constructor for ModemSim. 
ModemSimV2::ModemSimV2(int modems, double avgLen, int callIntrvl) 
: 
    r((int) time(0)), 
    // what about eventSet? 
    freeModems(modems), 
    avgCallLen(avgLen), 
    freqOfCalls(callIntrvl), 
{ 
    nextCall(freqOfCalls); // Schedule first call 
} 
+0

Also in der Push-Funktion sollte ich einen Verweis auf das Objekt akzeptieren? Push drückt auf ein Array von Zeigern. – dajee

+0

Ich habe eventSet-> Push (e); was schiebt den Zeiger e, und dann Array [Größe] = e; welcher sollte den Zeiger e dem Array in EventHeap zuweisen? – dajee

+0

@David: Das stimmt. –

0

eventSet wird als EventHeap* in ModemSimV2 erklärt, aber Sie initialisieren es nicht in den Konstruktor. Daher tritt bei der ersten Verwendung ein segfault auf.

ModemSimV2::ModemSimV2(int modems, double avgLen, int callIntrvl) 
: freeModems(modems), avgCallLen(avgLen), 
freqOfCalls(callIntrvl), r((int) time(0)) 
{ 
    eventSet = new EventHeap(); // <-- missing this initialization 

    nextCall(freqOfCalls); // Schedule first call 
} 

auch Speicherlecks zu vermeiden, werden Sie ein Destruktoren in ModemSimV2 und EventHeap müssen zuteilen den Speicher, den Sie zu befreien.