删除[]时出现分段故障
Segmentation Fault on delete[]
我一直在编写一个程序来模拟一个分配的分页系统。这个程序几乎可以工作,但由于某种原因,当我试图删除动态分配的帧数组时,我遇到了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类的构造函数使用。
- 分段故障(堆芯转储)矢量
- 数组的指针从不分段故障
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 分段故障 运行C++代码时出现 SIGSEGV
- 分段故障背包问题
- 分段故障 11,从类函数显示动态 C 字符串
- 面临分段故障 使用 ffmpeg 读取视频时,因为"pFormatCtx-> streams [i]-> codecpar"的地址0x00
- 在C++中,当指向删除和指向不同对象时,分段故障指针
- 分段故障说明
- 分段故障(核心转储)-不知道为什么
- 分段故障线程
- hiredis SET遇到分段故障
- 分段故障,合并排序算法
- 多线程程序中的分段故障和gdb回溯上的不完整信息
- 到达主C++之前分段故障
- 分段故障核心使用 IF流转储
- 使用向量的移动键盘排列(分段故障)
- 在二进制树插入和遍历期间,我得到了分段故障
- 分段故障在类之间返回整数
- C++分段故障BST