简体   繁体   中英

How to check valid allocation

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?

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.

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.

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.

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 throws std::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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM