【发布时间】:2011-12-06 19:59:54
【问题描述】:
假设我在 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);
}
编辑:我讨厌 malloc/free 和 new/delete,但不幸的是,我需要使用缓冲区来加载纹理,然后将这些纹理传递给 ID3D10ShaderResourceView、ID3D10Buffer、顶点缓冲区等。所有这些都需要指向缓冲区的指针。
我正在尝试使用异常而不是返回错误代码。 我还希望在需要它们的地方创建缓冲区,并在不再需要它们后立即释放它们。
然而,看起来很难看的是,如果出现错误,无论我返回错误代码还是抛出异常,我仍然应该记得清理到那时创建的任何缓冲区。如果我有 10 个缓冲区和 10 个可能的错误点,我将不得不调用 free() 100 次(在每个错误情况下记得释放每个缓冲区)。
现在假设我或更糟糕的是,我的同事想要更改一些逻辑,例如,在中间某处添加另一个缓冲区。现在,他必须仔细检查其余方法中可能发生的所有错误,并在每个这样的地方为该缓冲区添加 free()。如果他赶时间,他很容易忽略一些这样的地方,然后你就会出现内存泄漏。
这也极大地膨胀了代码。
finally 关键字可以解决 Java 或 C# 中的问题。无论异常发生在代码中的哪个位置,我仍然会在“finally”中清理所有这些缓冲区(顺便说一句,垃圾收集不需要这些缓冲区)。据我了解,在 C++ 中,我可能必须为任何此类缓冲区创建一个成员变量,并在析构函数中确保清理缓冲区。对我来说看起来也很丑陋,因为名称为“pBuffer”的成员变量,即使是私有变量,也只是垃圾,因为它仅用于一种方法(在本例中为构造函数),其余部分始终为 NULL时间。
一定是一个常见问题,但是我没有设法使用搜索找到答案。谢谢!
【问题讨论】:
-
除非绝对必要,否则您应该改掉在 C++ 中使用
malloc/free的习惯。更喜欢使用new/delete。 -
是的,但也不喜欢使用
new/delete:) 使用容器、智能指针等来避免手动管理内存。它们使保证异常安全变得更加容易。 -
标签: c++ exception constructor buffer free