VC6 using STL Note: Do not allow memory allocation failure to cause your legacy STL application to crash

Source: Internet
Author: User
Tags versions knowledge base

Most C + + developers use the standard module library (STL) extensively in their code. If you are one of them and are using the out-of-the-way STL and Visual C + + 6.0 directly, your application is in a highly dangerous state of collapse under low memory conditions. This problem arises because it is a rare practice to check whether operator new is failing. Worse, when new does fail, the response is not standard. Some language compilers return NULL, while other languages throw exceptions.

Also, if you are using STL in an MFC project, be aware that MFC has its own set of rules. This article discusses these issues, explains how to change the default behavior in Visual C + +. NET 2003, and outlines the changes that you must make if you use Visual C + + 6.0 so that you can safely use the STL when operator new fails.

How many developers check operator new for failure? Is it necessary to always check for failure? I've seen large, complex C + + projects written in Visual c++®6.0, where none of the entire code base checks to see if new returns NULL. Notice that I'm talking about checking to see if new returns NULL. In all versions of Visual C + + (up to version 6.0), the default behavior when operator new fails is to return NULL instead of throwing an exception. (For more information, see Knowledge Base article 167733, but do not implement the solution given in this article.) I'll explain why the solution should not be implemented later in this article.

The default behavior of Visual C + +. NET has changed, including version 7.0 (Visual C + +. NET 2002) and 7.1 (Visual C + +. NET 2003), which throws an exception when operator new fails. Although this new behavior under the Microsoft®.net Framework follows the C + + standard and is popular, it is necessary to note that it interrupts all migrated Visual C + + 6.0 style code runtime behavior that does not want operator new to throw an exception. If you are developing with Visual C + +. NET, you will find that the problems that are created here have been resolved. If you have not yet used a version of the. NET Framework, this article explores serious issues, such as implicit and incompatibility, when operator new returns NULL, which applies to all versions of the Visual C + + compiler, including version 6.0 and higher.

Background

When Microsoft publishes the first edition of the Visual C + + compiler, its primary role is to support the MFC framework. For all practical applications, Visual C + + and MFC are seen as a product. For years, MFC and Visual C + + compilers have matured. At the same time, the Visual C + + compiler has become a product of its own right, without having to rely on MFC and support other technologies such as the Active Template Library (ATL), the Standard Template Library (STL), and many other technologies. MFC is now just one of a variety of libraries supported by the Visual C + + compiler. Therefore, the use of Visual C + + development projects without MFC is now very common.

I started writing this article when I found that operator new failed and my STL code was behaving abnormally. To my surprise, I found that Visual C + + 6.0 (and all previous versions that support STL) were incompatible with the STL when operator new failed. I am working on a project that does not use MFC, so my observations are based only on non-MFC code. When I started to look at the MFC based examples, I found that MFC defines many different behaviors for operator new. Before delving into this article, I would like to summarize the behavior of operator new when memory allocation fails. For better comparisons, I'll talk about the behavior under Visual C + +. NET because it's different from previous versions.

The C + + standard declaration operator new should throw an exception when it fails. Specifically, the exception that is thrown should be Std::bad alloc. This is standard behavior, but the behavior in Visual C + + 6.0 depends on how you use it and what version you use. Figure 1 shows the Visual C + + behavior of operator new when memory allocation fails.

As you can see, only non-MFC code in Visual C + +. NET follows this standard. If you use MFC, then new throws an exception, but the type is incorrect. If the implementation of the STL you are using contains a catch (Std::bad alloc) statement that handles memory failure, then the only combination that works is a Visual C + +. NET without MFC. The STL implementation accompanying Visual C + + 6.0 uses catch (...) to handle operator new failure, so if you use MFC, the STL implementation that is included with Visual C + + 6.0 will operate correctly when operator new fails.

Assuming that the operator new implementation provided by MFC throws an exception (CMemoryException) and throws an exception (Std::bad::alloc) in the operator new of MFC in Visual C + +. NET, then I think that in all practical applications these situations will not cause problems. So what about the common scenario of using STL in a project based on Visual C + + 6.0 without using MFC? This is the focus of discussion in the remainder of this article.

Operator New returns NULL

Back to the question at the beginning of this article, in general, there are two reasons not to check whether the pointer value returned by operator new is NULL, one of which is: operator new never fails, or operator new throws an exception.

Even if you think operator new never fails, checking its return value is still not a good coding habit. Although desktop applications rarely experience out-of-memory conditions, users can still cause insufficient application memory when they press F9 on their 100MB Excel spreadsheet. A low memory condition is most likely to occur for server-based applications that want to run and process data 24 hours a day, especially on shared application servers. If an application is not guaranteed to leak a byte for a period of time, the chance of memory failure increases. How many applications, especially those internally developed, can provide this assurance?

If you do not check that the return pointer value is NULL because operator new will throw an exception, then you still have a sense of the original. After all, the C + + standard stipulates that new should throw an exception when it fails. This is not the default implementation of all versions of Visual C + + (when MFC is not used) until 6.0, and the implementation returns NULL when it fails. This is resolved in Visual C + +. NET, but there may be a problem with previous implementations, especially when using STL. The STL implementation throws an exception if new fails, regardless of the compiler used. In fact, if new does not occur and the memory allocation fails and returns NULL, then no STL behavior is defined, and it is likely to cause the application to crash. I'm going to show you a concrete example right now.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.