C++ 为什么迭代器指向的数据在从列表中删除后会被保留

C++ 为什么迭代器指向的数据在从列表中删除后会被保留,c++,list,iterator,C++,List,Iterator,在这个示例程序中,为什么即使列表为空,迭代器指向的数据的值也会保留? 是因为在C++中实现迭代器(即对象的值被保存到迭代器中)还是因为内存的分段被声明为免费使用,但还没有被改变? #include <iostream> #include <list> using namespace std; int main () { list<int> mylist; list<int>::iterator it = mylist.begin()

在这个示例程序中,为什么即使列表为空,迭代器指向的数据的值也会保留?
是因为在C++中实现迭代器(即对象的值被保存到迭代器中)还是因为内存的分段被声明为免费使用,但还没有被改变?
#include <iostream>
#include <list>
using namespace std;
int main ()
{
    list<int> mylist;
    list<int>::iterator it = mylist.begin();
    cout << "printing: " << *it << endl;

    mylist.push_back(77);
    mylist.push_back(22);

    // now front equals 77, and back 22

    mylist.front() -= mylist.back();
    it = mylist.begin();
    cout << "printing: " << *it << endl;
    cout << "mylist.front() is now " << mylist.front() << '\n';
    // trying to delete all elements and then see how the iterators are handling it
    it = mylist.begin();
    cout << "printing: " << *it << endl;
    mylist.remove(55);
    cout << "printing: " << *it << endl;
    mylist.remove(22);
    cout << "printing: " << *it << endl;
    cout << "mylist size: " << mylist.size() << endl;
    cout << "mylist.front() is now " << mylist.front() << '\n';
    cout << "printing: " << *it << endl;

    return 0;
}

迭代器因您的操作而无效,但它仍可能指向具有上一个值的内存。无论如何,从列表中删除值后访问它是未定义的行为。

\include
#include <stdio.h>

int main(int argc, char **argv)
{
    int *p = NULL;

    p = (int*)malloc(sizeof(int));

    *p = 5;

    printf("P: %d\n", *p);

    free(p);

    printf("P: %d\n", *p);
}
int main(int argc,字符**argv) { int*p=NULL; p=(int*)malloc(sizeof(int)); *p=5; printf(“P:%d\n”,*P); 自由基(p); printf(“P:%d\n”,*P); }
为什么这仍然是一个惊喜?将指针标记为无效与指针的存储位置无关

由于C语言中迭代器的实现,必然会发生这种情况吗++

不,这是未定义的行为。迭代器已无效,无法使用

是因为内存段声明为可用,但尚未更改吗

#include <iostream>
#include <list>
using namespace std;
int main ()
{
    list<int> mylist;
    list<int>::iterator it = mylist.begin();
    cout << "printing: " << *it << endl;

    mylist.push_back(77);
    mylist.push_back(22);

    // now front equals 77, and back 22

    mylist.front() -= mylist.back();
    it = mylist.begin();
    cout << "printing: " << *it << endl;
    cout << "mylist.front() is now " << mylist.front() << '\n';
    // trying to delete all elements and then see how the iterators are handling it
    it = mylist.begin();
    cout << "printing: " << *it << endl;
    mylist.remove(55);
    cout << "printing: " << *it << endl;
    mylist.remove(22);
    cout << "printing: " << *it << endl;
    cout << "mylist size: " << mylist.size() << endl;
    cout << "mylist.front() is now " << mylist.front() << '\n';
    cout << "printing: " << *it << endl;

    return 0;
}

是的,这就是为什么你观察到了你所观察到的。但是内存可能会被重新用于其他用途,或者无法访问-您不能依赖任何未定义行为的观察。

访问
front
当您的列表为空时是UB-可能旧数据仍然存在。或者恶魔会从你的鼻子里飞出来,这只是一种未定义的行为。迭代器已失效。@doctorlove:hahahah回答得很好,但我并不奇怪
*it
会打印55,即使它从列表中删除。“这是因为内存段声明为可用,但尚未更改。”(而且因为您很幸运,没有通过调用UB使程序崩溃或格式化硬盘驱动器)@abiessu:这就是它在这里的用法,只是一个例子,但有点修改。没有内存泄漏,只是访问一些不再有效的东西。@Chris这是不相关的。你有UB。可能有内存泄漏,以及其他令人讨厌的事情。@Chris-如果你的意思是“我仍然可以看到数据,那是泄漏吗?”那么不,这不是泄漏,只是内存还没有被重新使用。如果你的意思是“在我删除数据后,我还能使用这些数据吗,而且不用担心内存泄漏?”那么就不是了,因为无法保证数据在删除后会保留多久。@benjymous:(和Wojtek)我不是说看到数据泄漏。我与valgrind进行了检查,没有检测到泄漏。这是否会导致分割错误,因为在删除后(可能是免费的)内存不归我的程序所有?这可能会导致segfault。或者,您可能最终的内存区域仍然保存着旧的但仍然有效的数据。这就是为什么您避免UB。它可以在您的计算机上工作,但不能在其他人的计算机上工作。请参阅下面您对我的代码的评论。我已尝试将您的包含添加到段代码中,但无法提交edit导致它需要超过6个字符。此外,您的代码打印出这个
P:5p:0
,这正是重点。在我的系统上,我得到了5和5。UB是UB。我用C编写了我的代码,以说明指针以及它是如何融入语言思维的。您可以像使用原始代码一样轻松地使用new/delete或迭代器代码有。我也经历了
P:5p:0
,所以它很可能被覆盖。如果分配1000个元素,这种可能性就会降低,所以可能会得到
P:5p:5
#include <stdio.h>

int main(int argc, char **argv)
{
    int *p = NULL;

    p = (int*)malloc(sizeof(int));

    *p = 5;

    printf("P: %d\n", *p);

    free(p);

    printf("P: %d\n", *p);
}