如果使用std :: unique_ptr在退出作用域块时自动释放内存,为什么不只使用堆栈呢? [英] In the case of using a std::unique_ptr to automatically deallocate memory upon exiting a scoped block, why not just use the stack?

查看:1307
本文介绍了如果使用std :: unique_ptr在退出作用域块时自动释放内存,为什么不只使用堆栈呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是有关智能指针(例如唯一指针)的好答案:

但是,这引出了一个问题:在这种情况下,目标是简单地删除对象(释放内存),唯一指针指向该对象超出范围时,为什么不将整个对象放在上面像这样的堆栈?

void f()
{
    {
       MyObject myobj(my_constructor_param);
       myobj.DoSomethingUseful();
    } // myobj goes out of scope -- 
      // and is automatically destroyed.

    // myobj.Oops(); // Compile error: "myobj" not defined
                     // since it is no longer in scope.
}

在我看来,唯一逻辑可能是某些对象太臭了以至于它们可能会溢出堆栈,因为堆栈似乎限制在几十KB到几MB( C/C ++程序的最大堆栈大小),而堆可以成为数百GB!

有什么逻辑?在这里让我对唯一指针这个看似不必要的用例有一些了解.我想念什么?

相关:

  1. 要记住的堆栈的另一个功能是,可以存储在堆栈上的变量的大小受到限制(随OS的不同而不同).在堆上分配的变量不是这种情况. " ( https://gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html )

解决方案

虽然这本身并不是一个可怕的有用示例,但它会有一些细微的变化.

  1. 多态

struct Base { void blah() { std::cout << "Base\n";}};
struct Derived : Base { void blah() {std::cout << "Derived\n";}};

void blub(bool which) { 
    std::unique_ptr<Base> ptr = which ? new Base : new Derived;
    ptr->blah();
}

  1. 非标准删除器

{ 
    auto close = [] (FILE* fp) { fclose(fp);};
    std::unique_ptr<FILE, decltype(close)> ptr(fopen("name"), close);
} // closes file

  1. 动态数组(可以使用向量)

{ 
    std:: unique_ptr<int[]> ptr( new int [n]);
}

  1. 有条件地创建对象. (仅在C ++ 11和14中,此后使用std::optional)

void blah (bool smth)
{
    std::unique_ptr<T> opt;
    if (smth) {
        opt = std::unique_ptr<T>(new T);
    }
}

This is a great answer about smart pointers, such as unique pointers: What is a smart pointer and when should I use one?.

Here is an example they provide as the simplest use of a unique pointer:

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject(my_constructor_param));
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

However, this begs the question: in cases such as this, where the goal is to simply delete the object (free the memory) the unique pointer points to when it goes out of scope, why not just put the whole object on the stack instead, like this??

void f()
{
    {
       MyObject myobj(my_constructor_param);
       myobj.DoSomethingUseful();
    } // myobj goes out of scope -- 
      // and is automatically destroyed.

    // myobj.Oops(); // Compile error: "myobj" not defined
                     // since it is no longer in scope.
}

It seems to me the only logic can be that some objects are so stinking large they may overflow the stack, as stacks seem to be limited to a few dozen KB to a few MB (C/C++ maximum stack size of program), whereas a heap can be hundreds of GB!

What's the logic? Give me some insight here into this seemingly unnecessary use case of the unique pointer. What am I missing?

Related:

  1. "Another feature of the stack to keep in mind, is that there is a limit (varies with OS) on the size of variables that can be stored on the stack. This is not the case for variables allocated on the heap." (https://gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html)

解决方案

While this is not a terrible useful example per-se, it becomes with some slight variations.

  1. Polymorphism

struct Base { void blah() { std::cout << "Base\n";}};
struct Derived : Base { void blah() {std::cout << "Derived\n";}};

void blub(bool which) { 
    std::unique_ptr<Base> ptr = which ? new Base : new Derived;
    ptr->blah();
}

  1. Non-standard deleter

{ 
    auto close = [] (FILE* fp) { fclose(fp);};
    std::unique_ptr<FILE, decltype(close)> ptr(fopen("name"), close);
} // closes file

  1. Dynamic Array (you can arguably use a vector)

{ 
    std:: unique_ptr<int[]> ptr( new int [n]);
}

  1. Conditional creation of an object. (Only in C++11 and 14, after that use std::optional)

void blah (bool smth)
{
    std::unique_ptr<T> opt;
    if (smth) {
        opt = std::unique_ptr<T>(new T);
    }
}

这篇关于如果使用std :: unique_ptr在退出作用域块时自动释放内存,为什么不只使用堆栈呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆