【问题标题】:segmentation fault on inserting vector elements in a vector<vector>在向量<vector> 中插入向量元素时出现分段错误
【发布时间】:2021-08-06 15:30:19
【问题描述】:

在一个名为Stamp的类的构造函数中有两个向量:

  • vector&lt;double&gt; data 的大小为 data.size()
  • vector&lt;vector &lt;double&gt;&gt; collectedData 的大小为 [nsamples][data.size()/nsamples]

我需要循环它们才能有这样的东西:

  • collectedData[0][0-&gt;nsamples] 具有 data 的第一个“nsamples”元素
  • 'collectedData[1][0->nsamples]' 具有data 的第二个“nsamples”元素
  • ...
  • 'collectedData[i][0-&gt;nsamples]' 具有data 的第 i 个“nsamples”元素(如果我超过 data.size(),则为 '0')

这是我正在尝试的 C++ 代码,但我收到了分段错误。而且不明白是算法问题,还是vector的错误用法问题:

Stamp(vector<double> data, int nsamples) : data(data), nsamples(nsamples){
        long ll = data.size()/nsamples;
        int row;

        //Reserve space in collectedData:
        collectedData.reserve(nsamples);
        for (int i=0;i<nsamples;i++){
            collectedData[i].reserve(ll);
        }

        for (int i=0;i<=data.size();i+=nsamples){
     
            for (int j=0;(j<=nsamples)&&((row*i)<data.size());j++){
                collectedData[i].push_back(data[i]);
            }
            row++;
        }
    }

【问题讨论】:

  • i&lt;=data.size() off-by-one error 在这里。
  • .reserve(...)std::vector 上的.resize() 不同。在第一个循环中,collectedData[i] 无法返回对有效内部向量对象的引用,因为它尚未构造。长话短说:将第一个 reserve 更改为 resize
  • 感谢@MikeCAT,一个周期后仍然给出“分段错误(核心转储)”
  • collectedData.reserve(nsamples); 不保证有nsamples 元素,只是保证它们有足够的空间(即collectedData 仍然有相同的size(),但可能有不同的capacity() )。你想要resize
  • 你忘了初始化row

标签: c++ algorithm vector segmentation-fault computer-science


【解决方案1】:

首先,reserve() 函数只保留空间而不实际添加元素。您应该使用resize() 添加(或删除)元素。

其次,for循环中的条件i&lt;=data.size()是错误的。您不能使用data[data.size()]。应该是i&lt;data.size()

第三,似乎无法保证data.size() &lt;= nsamples,因此您应该再次添加元素,以免在第二个for 循环中导致collectedData[i] 超出范围访问。

最后,正如@molbdnilo 在评论中指出的那样,非静态局部变量row 的值是在没有初始化的情况下使用的。在使用之前,您应该为该变量设置一些适当的值。

Stamp(vector<double> data, int nsamples) : data(data), nsamples(nsamples){
        long ll = data.size()/nsamples;
        int row = 0; // initialize row

        //Reserve space in collectedData:
        if (collectedData.size() < nsamples){
            collectedData.resize(nsamples); // use resize() to add elements
        }
        if (collectedData.size() < data.size()){
            collectedData.resize(data.size()); // use resize() again to allocate enough size
        }
        for (int i=0;i<nsamples;i++){
            collectedData[i].reserve(ll); // using reserve() here because elements are added via push_back() later
        }

        for (int i=0;i<data.size();i+=nsamples){ // use correct condition
     
            for (int j=0;(j<=nsamples)&&((row*i)<data.size());j++){
                collectedData[i].push_back(data[i]);
            }
            row++;
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多