简体   繁体   English

push_back 到循环列表

[英]push_back to list in loop

I have a problem with pushing elements to a QList when iterating over it.我在迭代它时将元素推送到QList时遇到问题。 Let's see example code below:让我们看看下面的示例代码:

typedef struct
{
    int a[2];
} myType;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    QList<myType> list;

    // Create list
    for( int i = 0; i < 1000; i++)
    {
        list << (myType){ i, i };
    }

    int iteration = 0;

    for ( auto &i : list )
    {
        i.a[1] = 5;

        if ( ! (i.a[0] % 10) )
        {
            list.push_back( (myType){ 7, 7 } );
        }
        iteration++;
    }

    w.show();
    return a.exec();
}

When I debug the code I have a segmentation fault ( i got value 0xfeeefeeefeeefeee ):当我调试代码时,我遇到了分段错误( i得到了0xfeeefeeefeeefeee值):

在此处输入图像描述

What is the reason?是什么原因?

The reason for the segmentation fault is that altering the size of the container that you are looping over in a ranged-based for loop is undefined behavior.分段错误的原因是,更改您在基于范围的for循环中循环的容器的大小是未定义的行为。 Thus the loop needs to be rewritten.因此需要重写循环。

Looking at your code, you could still use the ranged-based for , but not alter the list.查看您的代码,您仍然可以使用基于范围的for ,但不能更改列表。 The following code seems to be equivalent (but not tested):以下代码似乎是等效的(但未经测试):

int numExtra = 0;
for ( auto &i : list )
{
    i.a[1] = 5;

    if ( ! (i.a[0] % 10) )
        ++numExtra;
    iteration++;
}

for (int i = 0; i < numExtra; ++i)
    list.push_back( (myType){ 7, 7 } );

Since the value being added to the list is the same value, the code just counts up the number of eventual push_back calls that will be invoked.由于添加到列表中的值是相同的值,因此代码只计算将被调用的最终push_back调用的数量。 After the initial loop is completed, we just call push_back a total of numExtra times.初始循环完成后,我们只调用push_backnumExtra次。

If you use iterator based for loop, this will still work if you are only appending to the list:如果你使用基于迭代器的for循环,如果你只是追加到列表中,这仍然有效:

for ( auto it = list.begin(); it != list.end(); ++it )
{
    it->a[1] = 5;

    if ( ! (it->a[0] % 10) )
    {
        list.push_back( myType({ 7, 7 }) );
    }
    iteration++;
}

With a range-based for , list.end() is evaluated only once at the start and so will become invalid when a new item is inserted.使用基于范围的forlist.end()在开始时仅评估一次,因此在插入新项目时将变为无效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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