0

プログラム内のポインターの配列にポインターを割り当てる際に問題が発生しました。関数が引数としてポインターを受け入れるように設定し、そのポインターを配列のインデックスに割り当てようとしました。正常にコンパイルされますが、実行されません。セグメンテーション違反が発生します。

エラーは、関数の最初の行であるEventHeap::pushから発生します。

何かアイデアはありますか?

私は助けに感謝します。

編集:特定の問題をすぐ下に投稿しますが、その下にある場合に備えてコードを残しておきます:D

セグメンテーション違反は、プッシュ機能の最初の行で発生します。

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++;
}

ソース:

// 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;
}

ヘッダ:

// 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
4

2 に答える 2

1

ここに手がかりがあります:

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

新しいオブジェクトを割り当て、そのコピーをプッシュしています。

別の手がかり:

// 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
}
于 2012-04-12T03:09:08.543 に答える
0

eventSetEventHeap*はinとして宣言されてModemSimV2いますが、コンストラクターで初期化しないでください。したがって、最初に使用すると、セグメンテーション違反が発生します。

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
}

また、メモリリークを回避するには、割り当てたメモリを解放するためにModemSimV2とEventHeapにデストラクタが必要です。

于 2012-04-12T04:40:06.130 に答える