使用指针删除未分配给新指针的内容

时间:2020-08-09 15:16:08

标签: c++ c++11 pointers struct

更新:请注意,由于我需要一行支持多个操作(将在python中使用),因此我被迫返回指向结果的指针

今天,我在编程生涯中遇到了最困难的问题,所以我希望有人能提供帮助。

graph_p.h中,我有:

typedef struct Graph* Graph_P;

(Graph_P是图形的指针)

Graph是我定义的另一个类

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函数(这是我们的主题):

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 +失败,我将删除graph_out的内容,这是不应该的。

建议的解决方案:

像这样在临时graph_out对象中保存Graph_P内容:

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

出了什么问题?

我正在将一个不是通过new分配的值放入graph_out内,因此,如果用户在函数外键入destroy(graph_out),那将是未定义的操作,因为我读到:

您只需要delete new

我该如何解决?

2 个答案:

答案 0 :(得分:2)

typedef struct Graph* Graph_P;

这是一个坏主意。应该避免混淆这样的指针。


问题在这里:

Graph tmp=*graph_out;
// ...
graph_out=&tmp;
return graph_out;

您将创建一个局部于函数的图形。函数返回时,它将自动销毁。您返回一个指向该图的指针。返回的指针将在函数外部无效。尝试通过该悬空指针删除或访问不存在的值会导致行为不确定。

答案 1 :(得分:-3)

我认为最简单的解决方案是在 destroy()函数中添加if语句,以确保graph_p不是nullptr:

void destroy(Graph_P graph_p)
{
    if (graph_p != nullptr) {
        delete graph_p;
    }
}

我认为将Graph_P用作智能指针(如果您至少使用C ++ 11)将是一个好主意-内存分配会更容易。