删除[]时出现分段故障

Segmentation Fault on delete[]

本文关键字:分段 故障 删除      更新时间:2023-10-16

我一直在编写一个程序来模拟一个分配的分页系统。这个程序几乎可以工作,但由于某种原因,当我试图删除动态分配的帧数组时,我遇到了segfault。

这是算法代码:

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和Request都是从文件加载的数据类型。请求只是一个数据结构,程序有一个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()函数本身。

我会作为一个评论来做这件事,但我的回复长度排除了这一点。我可以在程序中发现一些奇怪的地方,这些地方可能与你遇到的崩溃有关,也可能与之无关。

这很糟糕:

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类的构造函数使用。