标签: raii

RAII和堆栈展开

TIL,我对RAII和堆栈展开的'交织'(缺乏一个更好的词)的概念是完全(如果不是完全)错误.我的理解是使用RAII,防止任何/所有资源泄漏 - 甚至是可能由未处理的异常引起的泄漏.

然而,编写这个测试程序并随后磕磕绊绊地阅读本文/文档,让我意识到堆栈展开只会导致启用RAII的资源释放为try块中的自动启动,而不是自动在例如外部/其他范围内.

我对这个(新的)理解是否正确?或者还有其他细微差别我尚未掌握?那里的任何大师都想要进入?任何好的写作/分析/解释(堆栈展开)的指针都会有所帮助/赞赏......

c++ exception-handling exception raii stack-unwinding

0
推荐指数
1
解决办法
1507
查看次数

是否应该在析构函数中将指向"原始"资源的指针归零?

当我在C++类中包装"原始"资源时,在析构函数代码中,我通常只是释放已分配的资源,而不关注其他步骤,如清零指针等.例如:

class File
{
public:
  ...

  ~File()
  {
    if (m_file != NULL)
      fclose(m_file);
  }

private:
  FILE * m_file;
};
Run Code Online (Sandbox Code Playgroud)

我想知道这种代码风格是否包含潜在的错误:即是否可能不止一次调用析构函数?在这种情况下,在析构函数中正确的做法是清除指针以避免双重/多次破坏:

~File()
{
  if (m_file != NULL)
  {
    fclose(m_file);
    m_file = NULL; // avoid double destruction
  }
}
Run Code Online (Sandbox Code Playgroud)

可以为堆分配的内存做一个类似的例子:if m_ptr是指向分配的内存的指针new[],下面的析构函数代码是OK吗?

// In destructor:
delete [] m_ptr; 
Run Code Online (Sandbox Code Playgroud)

还是应该清除指针,以避免双重破坏?

// In destructor:
delete [] m_ptr;
m_ptr = NULL; // avoid double destruction
Run Code Online (Sandbox Code Playgroud)

c++ destructor raii

0
推荐指数
1
解决办法
224
查看次数

在C#中实现C ++ / clr的auto_handle功能

我一直在寻找一种方法,以确保在所有情况下(例如在类构造函数末尾的异常)都清除类的成员变量。

因为它们是成员变量,所以“尝试,捕获”和“使用”模式没有用。我注意到.NET C ++(C ++ / clr:safe)提供了对智能指针(称为msclr :: auto_handle)的仿真,例如auto_ptr或shared_ptr。这非常有用,因为我可以非常干净地确定性地破坏有限资源,例如线程或套接字。

我一直在分析用C ++ / clr生成的IL,并注意到它实际上所做的就是在修改封装数据的每个函数中都通过try / faults向IL垃圾邮件。

我已经为有兴趣的人列出了IL清单。(try / fault不是我添加的,而是C ++ / clr编译器添加的)

  MyClass()
  {
        myDisposable.reset(gcnew MyDisposable());
        throw gcnew Exception("Hello World");
        // myDisposable needs to clean up now
        // because it is very large or locks a limited resource.
        // Luckily with RAII.. it does!
  }
Run Code Online (Sandbox Code Playgroud)

...变成...

  .try
  {
  IL_0006:  ldarg.0
  IL_0007:  ldloc.0
  IL_0008:  stfld      class msclr.'auto_handle<MyDisposable>' modreq([mscorlib]System.Runtime.CompilerServices.IsByValue) MyClass::myDisposable
  IL_000d:  ldarg.0
  IL_000e:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0013:  ldarg.0
  IL_0014:  ldfld      class msclr.'auto_handle<MyDisposable>' …
Run Code Online (Sandbox Code Playgroud)

.net c# il raii

0
推荐指数
1
解决办法
727
查看次数

RAII应该导致内存泄漏吗?

#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

struct A
{
    A(char* p)
        : p(p)
    {}

    ~A()
    {   
        delete this->p;
    }

    char* p;
};

int main()
{
    A a(new char);
    _CrtDumpMemoryLeaks();
}
Run Code Online (Sandbox Code Playgroud)

在调试模式下运行后,Visual Studio 2012的输出窗口显示:

Detected memory leaks!
Dumping objects ->
{142} normal block at 0x007395A8, 1 bytes long.
 Data: < > CD 
Object dump complete.
Run Code Online (Sandbox Code Playgroud)

原因是什么?

c++ memory-leaks raii visual-c++

0
推荐指数
2
解决办法
223
查看次数

我应该将 RAII 应用于我分配的所有数组吗?

我现在正在学习 C++。这是一种非常复杂的语言,我不确定应该使用哪个功能以及何时使用。

C++ Primer 引入了 RAII 作为确保异常安全的方法。这是否意味着,作为一种良好的行为,当我想使用数组时,我应该将数组放入一个类中以分配和销毁资源。我知道我的想法很简单,或者说很幼稚。

我只是好奇什么是好的 C++ 编码行为。

c++ raii

0
推荐指数
1
解决办法
868
查看次数

objective-C的shared_ptr/weak_ptr实现

注意到如何妥善执行在当前Objective-C的引用计数(见这里这里),我敢肯定,必须有在那里提供类似于C++的东西图书馆shared_ptrweak_ptr语义没有所有这些荒谬的额外的调用retain,并release应自动调用何时(指针)变量超出范围

这可能在ObjC上吗?我知道ObjC没有析构函数,所以当变量超出范围时,没有办法自动调用,但这些retain/ release调用怎么可能真的有必要呢?我是以错误的方式绕过这个吗?

memory-management raii reference-counting objective-c

-1
推荐指数
1
解决办法
296
查看次数

为什么我们需要RAII来解决异常安全问题

unique_ptr<X> f()
{
    unique_ptr<X> p(new X);     // or {new X} but not = new X
    // do something - maybe throw an exception
    return p;   // the ownership is transferred out of f()
}
Run Code Online (Sandbox Code Playgroud)

当异常抛出时,为什么我们关心对象X的存在,为什么我们关心它占用的内存呢?

处理异常后,该过程将很快终止,内存将被释放,为什么我们关心这个?

c++ exception raii c++11

-2
推荐指数
2
解决办法
249
查看次数

在C++中,RAII是否总是在堆栈上分配对象,或者它是否曾使用堆?

我想知道RAII是否总是在堆栈上分配,或者编译器是否曾将堆用于大型对象(然后可能会在堆栈中添加一个令牌作为提醒何时销毁相应的堆分配对象)?

更新:显然这个问题一直被认为不清楚.也许一个代码示例将使这更清楚:

在这段代码中:

void dosomething() {
    MyClass myclass();
}
Run Code Online (Sandbox Code Playgroud)

假设编译器没有优化这样一个简单的例子,那么由此创建的MyClass实例是否总是在堆栈上分配,或者堆是否曾经使用过?

我想我现在理解了答案,这要归功于接受的答案 - 答案似乎是类实例本身在堆栈上,而其内容可能会或可能不会取决于它的构造函数是如何定义的.如果这不正确,请添加评论/答案.

c++ raii

-2
推荐指数
1
解决办法
570
查看次数

为什么在C++中需要析构函数?

为什么我们必须使用析构函数在c ++中取消分配内存,

我们可以使用

delete or delete[]   
Run Code Online (Sandbox Code Playgroud)

程序终止时释放程序使用的所有内存是不正确的.

c++ memory memory-management raii

-3
推荐指数
1
解决办法
339
查看次数