Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C+中引发异常时释放本地缓冲区+; 假设C++中有一个以下构造函数: MyClass::MyClass() { char* buffer = malloc(100); if (0 != someD3DXCallThatCanFail(..., buffer, ...)) { free(buffer); throw MyException(L"some message"); } char* buffer2 = malloc(200); if (0 != anotherD3DCallThatCanFail(..., buffer2, ...)) { free(buffer); free(buffer2); throw MyException(L"another message"); } .. more code here where buffer and buffer2 are still used free(buffer); free(buffer2); }_C++_Exception_Constructor_Buffer_Free - Fatal编程技术网

在C+中引发异常时释放本地缓冲区+; 假设C++中有一个以下构造函数: MyClass::MyClass() { char* buffer = malloc(100); if (0 != someD3DXCallThatCanFail(..., buffer, ...)) { free(buffer); throw MyException(L"some message"); } char* buffer2 = malloc(200); if (0 != anotherD3DCallThatCanFail(..., buffer2, ...)) { free(buffer); free(buffer2); throw MyException(L"another message"); } .. more code here where buffer and buffer2 are still used free(buffer); free(buffer2); }

在C+中引发异常时释放本地缓冲区+; 假设C++中有一个以下构造函数: MyClass::MyClass() { char* buffer = malloc(100); if (0 != someD3DXCallThatCanFail(..., buffer, ...)) { free(buffer); throw MyException(L"some message"); } char* buffer2 = malloc(200); if (0 != anotherD3DCallThatCanFail(..., buffer2, ...)) { free(buffer); free(buffer2); throw MyException(L"another message"); } .. more code here where buffer and buffer2 are still used free(buffer); free(buffer2); },c++,exception,constructor,buffer,free,C++,Exception,Constructor,Buffer,Free,编辑:我确实讨厌malloc/free和new/delete,但不幸的是,我需要使用缓冲区来加载纹理,然后将这些纹理传递给ID3D10ShaderResourceView、ID3D10Buffer、vertex buffer等。所有这些都需要指向缓冲区的指针。 我试图做的是使用异常,而不是返回错误代码。 我还希望在需要缓冲区的地方创建缓冲区,并在不再需要缓冲区后立即释放缓冲区 然而,看起来很难看的是,在发生错误的情况下,无论我返回错误代码还是抛出异常,我仍然应该记得清理在该点之前创建的任何缓冲区

编辑:我确实讨厌malloc/free和new/delete,但不幸的是,我需要使用缓冲区来加载纹理,然后将这些纹理传递给ID3D10ShaderResourceView、ID3D10Buffer、vertex buffer等。所有这些都需要指向缓冲区的指针。

我试图做的是使用异常,而不是返回错误代码。 我还希望在需要缓冲区的地方创建缓冲区,并在不再需要缓冲区后立即释放缓冲区

然而,看起来很难看的是,在发生错误的情况下,无论我返回错误代码还是抛出异常,我仍然应该记得清理在该点之前创建的任何缓冲区。如果我有10个缓冲区和10个可能的错误点,我必须调用free()100次(在每个错误情况下,记住释放每个缓冲区)

现在假设我或者更糟的是,我的同事想改变一些逻辑,比如说,在中间添加一个缓冲区。现在,他必须查看该方法其余部分中可能发生的所有错误,并在每个这样的位置为该缓冲区添加free()。如果他赶时间,他可以很容易地忽略一些这样的地方,你就会有内存泄漏

这也极大地膨胀了代码

最后,关键字将在Java或C#中解决该问题。无论异常发生在代码中的什么地方,我仍然会在“finally”中清理所有缓冲区(顺便说一句,垃圾收集不需要这些)。在C++中,我可能必须为任何这样的缓冲区创建一个成员变量,在析构函数中确保缓冲区被清除。在我看来也很难看,因为名为“pBuffer”的成员变量,甚至是私有变量,都是垃圾,因为它只在一个方法(在本例中是构造函数)中使用,并且在剩余时间内始终为NULL


这一定是一个常见的问题,但是我没有通过搜索找到答案。谢谢

标准答案是“资源获取就是初始化”(RAII)和智能指针的原则。在栈中创建一个类实例,该实例将释放析构函数中的内存,例如:C++ > Boo::SCONDEXYPTR .

。这个维基百科页面有C++样本。

再次搜索,对于“C++智能指针”。你需要在内存上有一个异常安全的包装器代替原始的<代码> MalOC ,正如你所注意到的,这带来了很多的麻烦,顺便说一下,它可以被<代码>操作符new < /C++ >取代。p>
前面的答案涵盖了这一领域。

停止手动管理内存,您将不会遇到此类问题。使用类似于
std::vector
的方法

或者,您可以使用类似于Boost的
共享_阵列
,但对于您在这里尝试的操作来说,这太过分了:

这里要说明的更一般的一点是,您应该使用RAII习惯用法——也就是说,当您获取资源时,您将它们存储在一个类的实例中,该类的析构函数将再次释放它们。然后,不管资源拥有类的实例是否超出范围,资源都会被释放

请看这里:

相反,请使用:

MyClass::MyClass()
{
std::向量缓冲器(100);
如果(0!=someD3DXCallThatCanFail(…))
{
抛出MyException(L“一些消息”);
}
std::向量缓冲区2c(200);
如果(0!=另一个可能失败的D3D调用(…)
{
抛出MyException(L“另一条消息”);
}
…这里有更多代码
}

这方面的标准答案在C++11中是唯一的。在此之前,可能
scoped\u ptr
(http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/scoped_ptr.htm)对于单例和
作用域数组
(http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/scoped_array.htm)对于阵列,两者都来自Boost。或者你可以自己编写等价的代码。

除非C++是绝对必要的,否则你应该在C++中使用<代码> MalC/Cube <代码>。更喜欢使用
new/delete
。正确,但不喜欢使用
new/delete
:)使用容器、智能指针等避免手动管理内存。它们使保证异常安全变得更加容易。@Dave-一旦你做到了这一点,就避免使用智能指针来实现更简单的生活(谢谢,我现在从你和其他人的回答中理解了RAII的概念)
MyClass::MyClass()
{
    std::vector<char> buffer(100);
    if (0 != someD3DXCallThatCanFail(...))
    {
        throw MyException(L"some message");
    }
    std::vector<char> buffer2c(200);
    if (0 != anotherD3DCallThatCanFail(...))
    {
        throw MyException(L"another message");
    }
    .. more code here 
}