[英]Deleting what wasn't allocated with new using pointers
更新:请注意,我被迫返回一个指向结果的指针,因为我需要在一行中支持多个操作(将在 python 中使用)
今天,我遇到了我编程生涯中最困难的问题,所以我希望有人能提供帮助。
在graph_p.h
我有:
typedef struct Graph* Graph_P;
(Graph_P 是一个 Graph 的指针)
虽然Graph
是我定义的另一个 class
在graph_p.cpp
我有以下功能:
Graph_P create()
{
try {
Graph_P graph=new Graph;
return graph;
}
catch (std::bad_alloc &) {
std::cout << "Error: Allocation Failed" << std::endl;
return nullptr;
}
}
void destroy(Graph_P graph_p)
{
delete graph_p;
}
以及下面的graphUnion
function (这是我们的主题):
Graph_P graphUnion(Graph_P graph_in1, Graph_P graph_in2, Graph_P graph_out) {
try {
*graph_out=(*graph_in1)+(*graph_in2);
//I have defined operator + between two graphs which returns a new graph built using default c'tor **not using new**
destroy(graph_out);
return graph_out;
}
catch (CException::exception &e) {
std::cout << e.what() << std::endl;
return nullptr;
}
}
有什么问题?
万一operator +
failed 我删除了不应该做的graph_out
的内容。
建议的解决方案:
graph_out
内容保存在临时Graph_P
object 中,如下所示:
Graph_P graphUnion(Graph_P graph_in1, Graph_P graph_in2, Graph_P graph_out) {
try {
Graph tmp=*graph_out;
tmp=(*graph_in1)+(*graph_in2);
destroy(graph_out);
graph_out=&tmp;
return graph_out;
}
catch (CException::exception &e) {
std::cout << e.what() << std::endl;
return nullptr;
}
}
有什么问题?
我在graph_out中放置了一个不是通过new
分配的值,所以如果用户在function之外键入destroy(graph_out)
,那将是一个未定义的动作,因为我读到:
您只需要delete
new
编辑的内容
我该如何解决这个问题?
typedef struct Graph* Graph_P;
这是一个坏主意。 应该避免像这样混淆指针。
问题在这里:
Graph tmp=*graph_out;
// ...
graph_out=&tmp;
return graph_out;
您创建一个 function 本地的图形。 当 function 返回时自动销毁。 您返回指向该图的指针。 返回的指针在 function 之外将无效。 尝试通过该悬空指针删除或访问不存在的值会导致未定义的行为。
我认为最简单的解决方案是在destroy() function 中添加 if 语句,以确保 graph_p 不是 nullptr:
void destroy(Graph_P graph_p)
{
if (graph_p != nullptr) {
delete graph_p;
}
}
我认为让 Graph_P 成为智能指针是个好主意(如果您至少使用 C++11)- memory 分配会更容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.