【问题标题】:Segmentation fault: randomly removing elements from 2d vector分段错误:从二维向量中随机删除元素
【发布时间】:2017-04-24 20:11:36
【问题描述】:

给定一个二维向量,我想随机检索然后删除一个元素,重复这个过程直到向量为空。

但是,我的代码在运行时返回 Segmentation fault: 11 错误,每次都在循环中的不同点。这告诉我代码正在尝试从不再存在的索引中检索元素,并且我一直在考虑解析索引或错误删除元素的方法。

关于如何解决此问题的任何建议?

#include <vector>
#include <iostream>

int main(void) {

    int X_LENGTH = 4;
    int Y_LENGTH = 4;
    std::vector<std::vector<long> > arrayCellDistance(X_LENGTH, std::vector<long>(Y_LENGTH, 0));

    // Assign values to array, print them out in order
    for (int i = 0; i < X_LENGTH; i++) {
        for (int j = 0; j < Y_LENGTH; j++) {
            arrayCellDistance[i][j] = (i+j)/2 + i*j;
            std::cout << "arrayCellDistance[" << i << "][" << j << "] = " << arrayCellDistance[i][j] << std::endl;
        }
    }

    std::cout << "===============================================" << std::endl;

    int x, y;
    srand(time(NULL));

    while (!arrayCellDistance.empty()) {

        y = (rand() % (int)(arrayCellDistance.size())); // Rand from 0 to number of rows
        x = (rand() % (int)(arrayCellDistance[y].size())); // Rand from 0 to number of columns in row

        // 'Retrieve' value from array and then delete this value
        std::cout << "arrayCellDistance[" << x << "][" << y << "] = " << arrayCellDistance[x][y] << std::endl;

        arrayCellDistance[y].erase(arrayCellDistance[x].begin() + 1); // Remove element

    }

    return 0;
}

删除后打印出矩阵时,我得到以下输出:

arrayCellDistance[0][1] = 0
0 1 1 0 
2 3 5 
1 3 6 8 
1 5 8 12 
arrayCellDistance[2][2] = 6
0 1 1 0 
2 3 5 
1 6 8 
1 5 8 12 
arrayCellDistance[1][1] = 3
0 1 1 0 
2 5 
1 6 8 
1 5 8 12 
arrayCellDistance[2][2] = 8
0 1 1 0 
2 5 
1 8 
1 5 8 12 
arrayCellDistance[1][0] = 2
Segmentation fault: 11

如您所见,当程序尝试删除第二行中的2 时,会出现分段错误 - 因此,由于仍然存在“行”向量,如果它仍然无法访问任何行?

【问题讨论】:

  • arrayCellDistance.size() + 1 - 1?为什么不简单地arrayCellDistance.size()
  • 考虑您的条件语句while(!arrayCellDistance.empty()) 是否处理第一级向量不为空但第二级向量之一为空的情况,然后您尝试从第二级向量中删除一个元素?
  • @Borgleader 很好 - 当包含+1 时,随机函数会产生[0, arrayCellDistance.size()] 范围内的整数,但也会尝试越界访问索引,因此将-1 添加到将范围更改为[0, arrayCellDistance.size() - 1]
  • @ChristopherPisz 我认为当二级向量中的所有元素都被擦除时,二级向量本身也被擦除,我错了吗?
  • @Daniel 二级向量将保留,它会是空的,但它仍然存在。所以,如果你再次尝试删除它,我想你会让电脑生气。

标签: c++ vector


【解决方案1】:

我现在手头没有编译器,但我认为您正在寻找类似的东西:

while (!arrayCellDistance.empty())
{
    y = (rand() % (int)(arrayCellDistance.size() ));    // Rand from 0 to number of rows

    if( arrayCellDistance[y].empty() )
    {
        // Error - Contained empty second-level vector initially.
        break;
    }

    x = (rand() % (int)(arrayCellDistance[y].size() )); // Rand from 0 to number of columns in row

    // Get value from array and display
    std::cout << "arrayCellDistance[" << x << "][" << y << "] = " << arrayCellDistance[x][y] << std::endl;

    // Remove element of second-level vector
    arrayCellDistance[y].erase( arrayCellDistance[y].begin() + x );

    // Remove empty first-level vector
    if( array[y].empty() )
    {
        arrayCellDistance.erase( arrayCellDistance.begin() + y );
    }
}

我们要确保我们正在处理空的二级向量,而不是在它们变为空后尝试从它们中删除。所以,这段代码在一个空向量变为空后将其移除。

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 2017-06-25
    • 1970-01-01
    • 2013-10-29
    • 2021-06-12
    • 1970-01-01
    • 2023-04-10
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多