Question

I've been writing a program to simulate a paging system for an assignment. The program almost works but for some reason I'm getting a segfault when I try to delete my dynamically allocated array of frames.

Here's the algorithm code:

int main(int argc, char* argv[])
{
    // Initialize page count
    PageCount = 0;

    // Validate input
    ValidateArgs(argc, argv);

    // Load programs and trace from list file
    Programs = LoadPrograms();
    Trace = LoadTrace();

    // Load main memory
    MainMemory Memory = MainMemory(Programs);

    // Run the Algorithm
    Run(Memory);

    // Print results
    Print();

    // Print the output to a file
    PrintOutput();
    return 0;
}

void Run(MainMemory memory)
{
    int page, frame;
    vector<int> replaceFrame;

    for (long i = 0; i < Trace.size(); i++)
    {
        // Get page and frame
        page = Programs[Trace[i].ProgramNum].GetPage(Trace[i].Word);
        frame = memory.IsInMemory(page);

        if (frame != -1)
        {
            // Access page
            memory.Frames[frame].Access(i);
        }
        else
        {
            // Find page to replace
            if (Algorithm == "clock")
            {
                replaceFrame = memory.FindClock();
            }
            else if (Algorithm == "lru")
            {
                replaceFrame = memory.FindLRU(i);
            }
            else
            {
                replaceFrame = memory.FindOldest(i);
            }

            // Replace page
            memory.Frames[replaceFrame[0]].Replace(page, i);

            // Replace with next contiguous page for prepaging
            if (HowToPage)
            {
                memory.Frames[replaceFrame[1]].Replace(
                    Programs[Trace[i].ProgramNum].GetNextPage(
                        Trace[i].Word), i);
            }
        }
    }

    return;
}

Program and Request are both data types loaded from files. Request is just a data struct and Program has a vector of ints as one of its members.

At the end of this function, my MainMemory object (the one that contains the dynamically allocated array) calls its destructor which is in my MainMemory struct:

struct MainMemory
{
    Frame* Frames;
    int Number;

    // Initializes an object of the MainMemory class
    MainMemory(vector<Program> thePrograms)
    {
        Number = MemorySize / PageSize;
        Frames = new Frame[Number];
        int numberProgs = thePrograms.size(), counter = 0;

        // Load main memory
        for (int i = 0; i < numberProgs; i++)
        {
            for (int j = 0; j < thePrograms[i].Pages.size(); j++)
            {
                int page = thePrograms[i].Pages[j];
                Frames[counter] = Frame(page, 0);

                if (counter + 1 < Number)
                {
                    counter++;
                }
                else
                {
                    return;
                }
            }
        }
    }

    // Initializes an object of the MainMemory class with another object
    //      of the MainMemory class
    MainMemory(const MainMemory& cpy)
    {
        *this = cpy;
    }

    // Sets one MainMemory equal to another
    MainMemory& operator=(const MainMemory& rhs)
    {
         Number = rhs.Number;
         Frames = new Frame[Number];

         for (int i = 0; i < Number; i++)
         {
             Frames[i] = Frame(rhs.Frames[i].Number,
                rhs.Frames[i].TimeStamp, rhs.Frames[i].UseCount,
                rhs.Frames[i].UseBit);
        }

        return *this;
    }

    // Deletes the MainMemory object
    ~MainMemory()
    {
        delete[] Frames;
        Frames = NULL;
    }
};

After some testing, I know that the Frames object has a memory address coming in to the destructor. Further, the code fails at the line indicated. The Frame struct doesn't have any dynamic elements so I didn't bother creating a destructor for it and instead let C++ do that for me.

struct Frame
{
    int Number;
    int TimeStamp;
    int UseCount;
    bool UseBit;

    // Initializes an empty object of the Frame class
    Frame() { }

    // Initializes an object of the Frame class
    Frame(int number, int time)
    {
        Number = number;
        TimeStamp = time;
        UseCount = time;
        UseBit = false;
    }

    // Initializes an object of the Frame class
    Frame(int number, int time, int count, bool use)
    {
        Number = number;
        TimeStamp = time;
        UseCount = count;
        UseBit = use;
    }

    // Simulates a replacement of one frame with a page from secondary
    void Replace(int page, int time)
    {
        Number = page;
        TimeStamp = time;
        UseCount = time;
        UseBit = true;
        PageFaults++;
        return;
    }

    // Simulates a memory access to the frame
    void Access(int time)
    {
        UseCount = time;
        UseBit = true;
        return;
    }
};

But clearly, something's not working so I'm wondering where I screwed up. Thanks for your help!

EDIT: I rechecked my constructor to see if it was shallow-copying anything. All elements in the copied element were in different locations from the original.

EDIT: I've been asked to add a SSCCE to this post:

int main(int argc, char* argv[])
{
    PageCount = 0;
    Programs = LoadPrograms();
    Trace = LoadTrace();
    MainMemory Memory(Programs);

    cout << endl << "Running algorithm" << endl;
    cout << endl << "Memory is at location " << &Memory << endl;
    Test(Memory);
    return 0;
}

void Test(MainMemory memory)
{
    cout << endl << "Memory at location " << &memory << endl;
    return;
}

This is the output I get:

Running algorithm

Memory is at location 0x7fff910a4eb0

Memory at location 0x7fff910a4ec0

In destructor

Frames in 0x7fff910a4ec0

Frames deleted

Destruction finished

It's copying correctly at least. Further, after changing the copy constructor, to explicitly copy the object (thanks Joachim Pileborg), it almost finishes executing Run(). However, there's still a problem with deallocating the memory. So, I think the issue is with the Run() function itself.

Was it helpful?

Solution

I would do this as a comment but the length of my reply precludes this. I can spot a number of oddities in the program that may or may not be related to the crash you are getting.

This is bad:

MainMemory(const MainMemory& cpy)
{
    *this = cpy;
}

You would be creating multiple references to pointers, alloying multiple deletions of the same memory block.

Here, you do not delete Frames before assigning a new value to it.

MainMemory& operator=(const MainMemory& rhs)
{
     Number = rhs.Number;
     Frames = new Frame[Number];

     for (int i = 0; i < Number; i++)
     {
         Frames[i] = Frame(rhs.Frames[i].Number,
            rhs.Frames[i].TimeStamp, rhs.Frames[i].UseCount,
            rhs.Frames[i].UseBit);
    }

    return *this;
}

I expect that this is causing the double deletions:

 MainMemory Memory = MainMemory(Programs);

is then causing your problem (combined with the first issue above). Should be:

MainMemory Memory (Programs) ;

I would also question the constructor use for the Frames class.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top