Reputation: 311
The code below is verifying if the allocation is correctly done using if(m_buf). (The code is from some video tutorial)
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);
}
}
I wander about two things.
First, Is it really necessary code?
Second, Is it really checking whether new char[len+1]
is successfully done.
It's just checking if something in char pointer can be true. I know c-string pointer only have first memory address of string but shouldn't it be valid about all string memory addresses? What I'm thinking is since operator new already has code throwing exception i guess, why don't they use try catch?
Let's say you have dynamically allocated object and if you want to check allocation is successfully done. What would you do? and do you think I should do this every time when I make an object?
Upvotes: 0
Views: 421
Reputation: 172934
The check is meaningless since it'll throw std::bad_alloc
when fails.
In case of failure, the standard library implementation calls the function pointer returned by
std::get_new_handler
and repeats allocation attempts until new handler does not return or becomes a null pointer, at which time it throwsstd::bad_alloc
.
Unless you're using non-throwing new like new(std::nothrow) char[len + 1];
, then the check might be meaningful.
returns a null pointer on failure instead of propagating the exception.
http://en.cppreference.com/w/cpp/memory/new/operator_new
Upvotes: 0
Reputation: 36607
This code is showing very old and obsolete technique. Early in the C++ standardisation process (early to mid 90s) the (then) draft standard a number of compilers/libraries only supported an operator new
that returned NULL on an error. For example, the ARM (a base document for the standardisation effort) did not suggest that operator new
would throw on failure.,
The requirements for operator new firmed up - and were finalised in the first C++ standard - so operator new
, by default, would throw an exception on failure which makes the test unnecessary
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);
}
}
but also require the caller to catch and handle the potentially thrown exception (std::bad_alloc
).
The test is still required if a different form of operator new
is used.
#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);
}
}
Of course, in modern C++, one wouldn't usually bother to write a String
class. Use of std::string
from <string>
would be preferred. std::string
's default allocator throws exceptions if memory allocation errors occur.
Upvotes: 1
Reputation: 11434
The check is not necessary (at least in this form).
An unsuccessful new
will throw an exception (std::bad_alloc
). In your code, it will exit the function, so the if
is not necessary.
There is a nothrow
variant of new which will return a nullptr
instead of throwing, but to use that, you need to write it explicitly.
Upvotes: 0
Reputation: 1134
This is a pointless check, unless you work with non-standard compilers. new
can never return nullptr
, it can only fail with a bad_alloc
exception, in which case the if
-check is never even reached.
Upvotes: 1