C + + trap based on range loop (range-based for Loop)

Source: Internet
Author: User
Tags gettext

The range-based loop of C + + is a new feature of c++11, and it is convenient to replace the for loop usage of iterators to some extent. However, a range-based for loop has a hidden trap that can cause serious memory errors if you are not aware of it.

Examples Show

Look at the following code:

1#include <iostream>2#include <string>3 4 using namespacestd;5 6 structMyClass7 {8     stringText ="MyClass";9 Ten     string&GetText () One     { A         returntext; -     } - }; the  - intMain () - { -      for(Auto Ch:myclass (). Text) +     { -cout <<ch; +     } Acout <<Endl; at}

This code is very simple, the output is "MyClass". But if you modify line 18th slightly, change to the following:

     for (Auto Ch:myclass (). GetText ())    {        << ch;    }

As a result, nothing is output and the program exits directly. To understand why this behavior occurs, first know how the scope-based for loop is defined.

Scope-based for loop definition

In the C++11 standard, it has the following format

attr (optional) for (range_declaration:range_expression) loop_statement

Where attr is optional, the range_declaration portion corresponds to the "Auto ch" in our code, and the range_expression portion corresponds to "MyClass ()." GetText () ", Loop_statement is" { cout << ch; }"

The standard specifies that the above loop expression should be equivalent to

{    && __range = range_expression;      for (Auto __begin = begin_expr, __end = end_expr; __begin! = __end; + +__begin        ) {= *__begin;        Loop_statement    }}

Where begin_expr and end_expr are determined by the type of range_expression.

It is worth noting that the __range type declared in the first line is "Auto &&", so if Range_expression is a temporary object with an rvalue, __range can prolong the lifetime of range_expression.

Problem analysis

After looking at the definition of the for loop for the given range, the reason for the problem in the previous example is clear.

In the original example, Range_expression is "MyClass (). Text", MyClass () is a temporary object, and the expression "MyClass ()" is the right value. Therefore, the expression "MyClass (). Text" is also an rvalue, "MyClass (). Text" This object is part of the temporary object. So, in the "auto && __range = range_expression;" Statement, Auto is deduced as "std::string". When initializing an rvalue reference as part of a temporary object, the lifetime of the entire temporary object can be extended, and the temporary object is destroyed when the reference is destroyed. So the For loop can execute normally.

But after the modification, range_expression is "MyClass (). GetText ()". Similarly, MyClass () is a temporary object, and the expression "MyClass ()" is the right-hand value. However, the return type of "GetText ()" is "string&", so the expression "MyClass (). GetText ()" is an lvalue. So, in "auto && __range = range_expression;" In this statement, Auto is deduced as "string &" and the statement is equivalent to "string & __range = range_expr ession; ". Although the "MyClass (). GetText ()" Object is part of a temporary object, it does not extend the lifetime of the temporary object when initializing a non-const lvalue reference, so the temporary object is destroyed at the end of the initialization statement MyClass (), __ Range becomes a wild reference, so a memory error may occur with subsequent loop statements.

Summarize

The range-based for loop is convenient, and can even traverse temporary objects, which are often used in everyday life. Note, however, that if you want to traverse a temporary object, the temporary object that needs to be traversed must be an rvalue expression, and notice that other temporary objects in the middle of the expression are destroyed before the loop starts, and only the last temporary object returned by the expression is "saved".

C + + trap based on range loop (range-based for Loop)

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.