C++ 如何判断是否删除从函数返回的指针

C++ 如何判断是否删除从函数返回的指针,c++,memory-leaks,C++,Memory Leaks,考虑一个返回类型*的函数,因此它看起来可以在其定义中分配类型,但您无法确定(有许多函数,您没有时间阅读它们的定义) 如何判断是否应该删除返回的指针?例如,这是一种类型: struct MyStruct { MyStruct(void) { cout << "Created.\n"; } ~MyStruct(void) { cout << "Deleted.\n"; } }; Func1分配了一个指针,您应该稍后取消分配它。但可能定义是其他的,指针不应该是

考虑一个返回
类型*
的函数,因此它看起来可以在其定义中分配
类型
,但您无法确定(有许多函数,您没有时间阅读它们的定义)

如何判断是否应该删除返回的指针?例如,这是一种类型:

struct MyStruct
{
    MyStruct(void) { cout << "Created.\n"; }
    ~MyStruct(void) { cout << "Deleted.\n"; }
};
Func1分配了一个指针,您应该稍后取消分配它。但可能定义是其他的,指针不应该是
delete
d

我的问题是:如何判断是否删除指针?例如:指针可能是静态的

MyStruct* Func2(void)
{
    static MyStruct* ms = &MyStruct();
    return ms;
}
取消分配此指针将使整个程序崩溃


提前感谢。

无法通过编程检查此问题。1作为程序员,您需要了解哪些内容需要删除,哪些内容不需要删除

更一般地说,这是一个原因,在C++中传递原始指针常常是不赞成的。通常用于管理动态分配的内存


1.至少,不是以一种健壮的独立于平台的方式

如何判断是否应该删除返回的指针

不能,这就是为什么使用原始指针来管理内存是一个非常糟糕的主意的原因之一。如果一个对象需要删除,那么应该总是使用智能指针自动完成

这还有一个优点,即动态对象在使用完毕后总是会被删除,即使抛出异常也是如此

std::unique_ptr<MyStruct> Func1()
{
    return std::unique_ptr<MyStruct>(new MyStruct);
}

void do_something()
{
    auto thing = Func1();
    do_something_with(thing);

    // The object is automatically deleted here
    // even if the function threw an exception.
}
std::unique_ptr Func1()
{
返回std::unique_ptr(新MyStruct);
}
空做某事
{
auto thing=Func1();
用(东西)做某事;
//该对象将在此处自动删除
//即使函数抛出异常。
}

如果您被迫使用一个设计糟糕的库,其中的函数返回指针可能需要删除,也可能不需要删除,那么您唯一的选择就是阅读文档或找到更好的库。最好立即将任何需要删除的指针指定给智能指针,这样您至少具有异常安全性。

我完全同意Mike和Oli的观点,只需补充一点:如果库写得很好,然后可能会有一些标准用来指出什么时候你是函数返回的指针的所有者(这意味着你必须删除它)。这可以通过命名或函数属于某个类/命名空间来实现。在这种情况下,可以避免读取每个函数的定义

事实:如果你没有时间阅读API上的文档,那么你就会有bug

这归结为一个原则,函数总是做出许多假设,这些假设都是由不同的机制执行的:

  • 有些是由编译器自动执行的,通常通过类型执行。例如,如果函数必须假定它可以写入某个参数,则其类型将为非常量,并且传递常量参数将导致编译器错误。这是防止bug的最好方法。返回智能指针是为指针所有权提供编译器强制的一种方法,因此不需要文档。这就是为什么我们更喜欢模板或基类而不是
    void*
  • 有些是通过惯例或惯例暗示的。同样,这意味着您不需要阅读文档来遵守函数的假设,因为这对于任何有能力的程序员来说都是显而易见的。例如,如果C++函数要求网格的行或列,则可以期望它是基于0的。这是惯例。或者,对于您的情况,如果函数返回一个引用,则按照约定,调用方不应删除该对象
  • 仍然有许多假设根本无法实施,除非通过文档。例如,您无法知道函数是否将执行边界检查或接受空指针。作为一名API开发人员,如果可以的话,您应该避免这种情况,但是面对这种情况,您不能忽略文档

  • 作为C++开发人员,我们尽可能努力尽可能地使用1,但其他的不能完全避免。OP的“你没有时间阅读他们的定义”不是一个选项。不同意“在任何情况下”-将指向静态的指针指定给智能指针是不明智的…@OliCharlesworth:是的,我有点不清楚;我只是指动态对象的情况。

    std::unique_ptr<MyStruct> Func1()
    {
        return std::unique_ptr<MyStruct>(new MyStruct);
    }
    
    void do_something()
    {
        auto thing = Func1();
        do_something_with(thing);
    
        // The object is automatically deleted here
        // even if the function threw an exception.
    }