gpt4 book ai didi

C++链表段错误

转载 作者:行者123 更新时间:2023-11-30 02:10:53 24 4
gpt4 key购买 nike

我正在编写一个程序作为学校的作业,虽然我已经解决了所有错误,但直到我决定调用我的复制构造函数。该程序是交互式的 (CLI),它基本上有两个模块:一个用于 LList 类的 .h 和 .cpp 文件,一个用于程序结构的 .h 和 .cpp 文件,还有一个仅用于 main() 的第三个 cpp 文件。它假设是一个水电工程公司(假公司)的程序,其中 LList 节点保存河流中年度水流量(年份和流量)的数据。以下是对类(class)的一些见解:

//list.h
struct ListItem {
int year;
double flow;
};

struct Node {
ListItem item;
Node *next;
};

class FlowList {
public:
FlowList();
// PROMISES: Creates empty list

FlowList(const FlowList& source);
// REQUIRES: source refers to an existing List object
// PROMISES: create the copy of source

~FlowList();
// PROMISES: Destroys an existing list.

FlowList& operator =(const FlowList& rhs);
// REQUIRES: rhs refers to an existing FlowList object
// PROMISES: the left hand side object becomes the copy of rhs

//....Other member functions

private:
// always points to the first node in the list.

Node *headM;
// Initially is set to NULL, but it may point to any node.

Node *cursorM;
//For node manipulation within interactive CLI

void copy(const FlowList& source);

void destroy();

我相信内存泄漏或冲突发生在复制函数的某处,但无法指出具体位置。

//list.cpp

FlowList::FlowList() : headM(0), cursorM(0) {}

FlowList::FlowList(const FlowList& source)
{
copy(source);
}

FlowList::~FlowList()
{
destroy();
}

FlowList& FlowList::operator =(const FlowList& rhs)
{
if (this != &rhs)
{
destroy();
copy(rhs);
}
return (*this);
}

//...more function definitions

void FlowList::copy(const FlowList& source)
{
if (source.headM == NULL)
{
headM = NULL;
cursorM = NULL;
return;
}

Node* new_node = new Node;
assert(new_node);
new_node->item.year = source.headM->item.year;
new_node->item.flow = source.headM->item.flow;
new_node->next = NULL;
headM = new_node;

Node* thisptr = new_node;

for(Node* srcptr = source.headM->next; srcptr != NULL; srcptr = srcptr->next)
{
new_node = new Node;
assert(new_node);
new_node->item.year = srcptr->item.year;
new_node->item.flow = srcptr->item.flow;
new_node->next = NULL;
thisptr->next = new_node;
thisptr = thisptr->next;
}

}

void FlowList::destroy()
{
Node* ptr = headM;
Node* post = headM->next;

while (ptr != NULL)
{
delete ptr;
ptr = post;
if (post)
post = ptr->next;
}
headM = NULL;
}

如果我创建一个 FlowList 对象并用 .dat 文件中的数据填充它,程序就可以正常工作;然后我可以在程序中操作数据(显示、执行计算、添加到列表、从列表中删除并将数据保存到文件)但是如果我创建另一个 FlowList 对象(在 main.cpp 中)程序崩溃(段错误)。任何帮助将非常感激。

最佳答案

我首先发现的是,如果列表为空,您的 destroy() 函数看起来总是会出现段错误:

void FlowList::destroy()
{
Node* ptr = headM;
Node* post = headM->next;
//...
}

如果列表为空,headMNULL 然后您尝试执行 headM->next 这将始终产生在这种情况下出现段错误。

我认为如果您传入一个空列表,您的复制构造函数中也可能会发生内存泄漏。如果您查看这段代码:

void FlowList::copy(const FlowList& source)
{
if (source.headM == NULL)
{
headM = NULL;
cursorM = NULL;
return;
}
//...
}

如果当前列表包含 20 个项目并且 source 是一个空列表怎么办?您将当前列表的 headMcursorM 设置为 NULL,但是您永远不会在列表中的任何节点上调用 delete您最初使用 new 创建的当前列表。您可能也想在复制构造函数中的某个地方使用 destroy() 函数(您为 operator= 函数做了这件事)。

我注意到的最后一件事是您没有在 copy() 函数中为非空列表初始化 cursorM(@Akusete 也指出了这一点).我想我建议在复制构造函数的开头,只需将 cursorMheadM 初始化为 NULL 即可覆盖您的基础。

看起来你真的很接近,我认为你真的需要仔细考虑处理空列表的边界情况(在 LHS 和 RHS 上),你可能会发现其中的大部分错误。祝你好运!

关于C++链表段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4251487/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com