delete []上的分段错误

时间:2014-04-27 16:14:00

标签: c++ segmentation-fault destructor dynamic-arrays

我一直在编写一个程序来模拟分配的分页系统。该程序几乎可以工作,但出于某种原因,当我尝试删除动态分配的帧数组时,我得到了段错误。

这是算法代码:

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

程序和请求都是从文件加载的数据类型。请求只是一个数据结构,而程序有一个int的向量作为其成员之一。

在这个函数的最后,我的MainMemory对象(包含动态分配的数组的对象)调用它在我的MainMemory结构中的析构函数:

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

经过一些测试,我知道Frames对象有一个内存地址进入析构函数。此外,代码在指示的行处失败。 Frame结构没有任何动态元素,所以我没有为它创建析构函数,而是让C ++为我做这件事。

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

但显然,有些东西没有用,所以我想知道我搞砸了哪里。 谢谢你的帮助!

编辑:我重新检查了我的构造函数,看它是否是浅层复制任何东西。复制元素中的所有元素都与原始元素位于不同的位置。

编辑:我已被要求在此帖中添加SSCCE:

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

这是我得到的输出:

运行算法

内存位于0x7fff910a4eb0

位置

内存位置0x7fff910a4ec0

在析构函数中

0x7fff910a4ec0中的帧

删除了框架

销毁完毕

至少正确复制。此外,在更改复制构造函数后,为了显式复制对象(感谢Joachim Pileborg),它几乎完成了执行Run()。但是,释放存储器仍然存在问题。所以,我认为问题在于Run()函数本身。

1 个答案:

答案 0 :(得分:-1)

我会这样做作为评论,但我的答复的长度排除了这一点。我可以发现程序中的一些奇怪的东西可能与你遇到的崩溃有关,也可能没有。

这很糟糕:

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

您将创建对指针的多个引用,合并同一内存块的多个删除。

在此,您不会在为其分配新值之前删除帧。

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

我希望这会造成双重删除:

 MainMemory Memory = MainMemory(Programs);

然后导致您的问题(与上面的第一个问题相结合)。应该是:

MainMemory Memory (Programs) ;

我还会质疑Frames类的构造函数用法。