以下代码使用if(m_buf)验证分配是否正确完成。 (代码来自一些视频教程)
char *m_buf;
void String::_copy(const char* lpsz){
if (lpsz != 0){
int len = MyCString::strlen(lpsz);
m_buf = new char[len + 1];
if (m_buf)
MyCString::strcpy(m_buf, lpsz);
}
}
我徘徊了两件事
首先,它真的是必要的代码吗?
第二,是否真的检查new char[len+1]
是否成功完成
它只是检查char指针中的某些内容是否为真。我知道c-string指针只有字符串的第一个内存地址但是它不应该对所有字符串内存地址有效吗?我的想法是因为操作员新的已经有代码抛出异常我猜,为什么他们不使用try catch?
假设您已动态分配对象,并且如果要检查分配是否已成功完成。你会怎么做?你认为我每次制作一个物品时都应该这样做吗?
答案 0 :(得分:1)
这是一个毫无意义的检查,除非您使用非标准编译器。 new
永远无法返回nullptr
,它只能在bad_alloc
例外情况下失败,在这种情况下,if
- 检查永远不会到达。
答案 1 :(得分:1)
此代码显示了非常古老和过时的技术。在C ++标准化过程的早期(90年代早期到中期)(然后)草案标准中,许多编译器/库仅支持在错误上返回NULL的运算符new
。例如,ARM(标准化工作的基础文档)并未建议运算符new
将失败。
运算符new的要求已经确定 - 并且已经在第一个C ++标准中完成 - 所以默认情况下,运算符new
会在失败时引发异常,这使得测试变得不必要
void String::_copy(const char* lpsz
{
if (lpsz != 0)
{
int len = MyCString::strlen(lpsz);
m_buf = new char[len + 1];
MyCString::strcpy(m_buf, lpsz);
}
}
但还要求调用者捕获并处理可能抛出的异常(std::bad_alloc
)。
如果使用不同形式的运算符new
,则仍需要进行测试。
#include <new>
void String::_copy(const char* lpsz
{
if (lpsz != 0)
{
int len = MyCString::strlen(lpsz);
m_buf = new (std::nothrow) char[len + 1];
if (m_buf) MyCString::strcpy(m_buf, lpsz);
}
}
当然,在现代C ++中,人们通常不会费心去编写String
类。最好使用std::string
中的<string>
。如果发生内存分配错误,std::string
的默认分配器会抛出异常。
答案 2 :(得分:0)
不需要检查(至少以这种形式)。
不成功的new
会抛出异常(std::bad_alloc
)。在您的代码中,它将退出该函数,因此if
不是必需的。
新版本的nothrow
变体将返回nullptr
而不是投掷,但要使用它,您需要明确地编写它。
答案 3 :(得分:0)
检查没有意义,因为它会在失败时抛出std::bad_alloc
。
如果失败,标准库实现会调用
std::get_new_handler
返回的函数指针,并重复分配尝试,直到新处理程序不返回或变为空指针,此时它会抛出std::bad_alloc
。
除非你使用像new(std::nothrow) char[len + 1];
这样的非投掷新内容,否则检查可能会有意义。
在失败时返回空指针,而不是传播异常。