C + + wild pointers in combat

Source: Internet
Author: User
Tags call back

A: Today do POJ on the 3750 that the problem, the use of the list of the Erase method, after submission is always reported runtime error! Tangled for a very long time. There were once suspected vectors of the erase and list of the erase processing method is not the same. For theoretical knowledge Please refer to also pointer and hover pointer: http://blog.csdn.net/u010700335/article/details/39831293 or deep copy and light copy click to open link http://blog.csdn.net/ u010700335/article/details/39830425


Second: We enclose the code and explain it later.

#include <iostream> #include <cstdio> #include <cstring> #include <list>using namespace std; const INT max_size = 20;int Main () {    int n,w,s;    int I,CP;    Char str[max_size];    list<string> lists;    scanf ("%d", &n);    for (i=0;i<n;i++)    {        cin >> str;        Lists.push_back (str);    }    scanf ("%d,%d", &w,&s);    List<string>::iterator iter;iter = Lists.begin (); while (w>1) {iter++;w--;} CP = 1;    for (; Lists.size ()!=0;)    {        cp++;        if (iter = = Lists.end ())            iter = Lists.begin ();        if (cp<=s)        {            iter++;        }        else        {            cout << *iter << Endl;            iter = Lists.erase (ITER);//Because the removal of ITER automatically returns the next element, the vector is the same, otherwise the TER becomes the wild pointer, instead of automatically pointing to the next, is to return to the next.            CP = 1;        }    }    return 0;}
Three: The reasons are as follows:

A list container is used inside the program, and today the mechanism of the erase () function is understood. The usual way to delete elements in a container is as follows (Method 1):
list< int> List;
list< Int>::iterator iter;
for (iter = List.begin (); ITER! = List.end ();)
{
if (1)
{
iter = List.erase (ITER);
}
Else
{
iter++;
}
}


You can also write this (method 2):
list< int> List;
list< Int>::iterator iter;
for (iter = List.begin (); ITER! = List.end ();)
{
if (1)
{
List.erase (iter++);
}
Else
{
iter++;
}
}


There is a wrong way of writing (note the comparison with Method 2)
list< int> List;
list< Int>::iterator iter;
for (iter = List.begin (); ITER! = List.end ();)
{
if (1)
{
List.erase (ITER);
}


iter++;
}//

Let's take a look at the source code of the Erase () function (listing only the codes under release).
Iterator Erase (iterator _where)
{//Erase element at _where
_nodeptr _pnode = (_where++). _mynode ();


if (_pnode! = _myhead)
{//Not list head, safe to erase
_nextnode (_prevnode (_pnode)) = _nextnode (_pnode);
_prevnode (_nextnode (_pnode)) = _prevnode (_pnode);
This->_alnod.destroy (_pnode);
This->_alnod.deallocate (_pnode, 1);
--_mysize;
}
return (_where);
}

when the function returns, it returns the next node of the current iterator. So when iter = List.erase (ITER); After execution, the iterator automatically points to the next element.for the entry of ITER, the address is destroyed, so when writing, should pay attention to add the front of iter =

Four: iter++ and ++iter

The other way of writing, List.erase (iter++); Why is it right? Here we have a look at the operation of the + + operator.
_myt_iter& operator++ ()//front self-increment
{//Preincrement
+ + (* (* (_mybase_iter *) this);
return (*this);
}


_myt_iter operator++ (int)//back self-increment
{//Postincrement
_myt_iter _tmp = *this;
++*this;
return (_TMP);
}


+ + can actually be seen as a function.
For + + in the latter case (for example, i++), the function at the time of operation, the operation of the data I has changed, but the return value of the function is the data before the operation, so in our opinion, i++ seems to be the first I read, only +1.
Back to the iterator, List.erase (iter++); there's no problem.
For the wrong way, List.erase (ITER); After execution, the object that ITER refers to has been destroyed, so it is illegal to operate on ITER and the program will go wrong.


Let's look at a simple example:

#include <iostream>using namespace Std;class a{public:a (int a=0,int b=0) {x=a;y=b;} a& operator++ (); A operator++ (int); void out () {cout<<x<< "," <<Y<<ENDL;} Private:int x, y;}; a& a::operator++ () {X++;y++;return *this;} A a::operator++ (int) {return *this;x++;y++;} void Main () {A ta (on), TB (ta.out); Tb.out ();(++ta). Out ();(tb++). Out (); According to the form of the book wrote a program,a& pre-and a-type back, the program is correct, there is a question: why the compiler will automatically call the a& type, a type. How does it know that when the + + number is in front of TA, to call the a&;++ number after TA, to call A;

The overloaded + + symbol is not used by the compiler to differentiate whether the + + is pre-or post-built? is based on (int) to differentiate when a given argument, such as 0, is a post-
opertor++ ();//heavy-duty front + +
operator++ (int); Heavy-duty Post + +


c.opertor++;//calling the predecessor
c.opertor++ (0);//Call Back
This is a conventional



C + + wild pointers in combat

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.