向量迭代器不可取消引用 C++

Posted

技术标签:

【中文标题】向量迭代器不可取消引用 C++【英文标题】:vector iterator not dereferencable C++ 【发布时间】:2016-04-03 10:09:45 【问题描述】:

我正在尝试通过使用向量中的 (max_element-min_element) 来设置浮点数的值。我正在循环其中的几个,因此是浮点向量和向量向量。

我收到以下错误:

Expression: Vector iterator not dereferencable

vector<float> amplitudeStorage;
vector<vector<float>> vectorStorage;    


 int main()

       for (int i = 0; i < amplitudeStorage.size(); i++) 
       
        AssignWaveAmplitude(amplitudeStorage[i], vectorStorage[i]);
       
  

它发生在函数调用上。函数如下所示:

void AssignWaveAmplitude(float amplitudeVariable, vector<float> dataVectorr) 

    amplitudeVariable = (*max_element(begin(dataVectorr), end(dataVectorr))) - (*min_element(begin(dataVectorr), end(dataVectorr)));

有谁知道如何解决这个问题?

非常感谢。

EDIT1:这个问题的解决方案是这个问题的第一条评论。我使用的一些向量是空的,这导致了错误。

EDIT2:

@WhozCraig 所以现在我已经做到了:

for (int i = 0; i < amplitudeStorage.size(); i++) 
    amplitudeStorage[i] =AssignWaveAmplitude(vectorStorage[i]);                                   
    

还有这个:

float AssignWaveAmplitude( vector<float> dataVectorr) 

    return (*max_element(begin(dataVectorr), end(dataVectorr))) - (*min_element(begin(dataVectorr), end(dataVectorr)));

但所有的花车仍然出现相同的数字。知道为什么吗?

EDIT3:事实证明,浮点数出现错误的原因是因为我输出错误。

我在做: cout &lt;&lt; lowerBackYAmplitude&lt;&lt; endl (这是幅值存储中的值之一)

我应该做的:

for (int i = 0; i < amplitudeStorage.size(); i++)
                
                    cout << amplitudeStorage[i] << endl;
                

【问题讨论】:

这是一个想法。将原本过高的单行分解成几部分,然后查看您要取消引用结束迭代器的那些 one 行程。我猜,dataVector 是空的。当然,如果没有 MCVE,这就是你所能得到的一切。 @WhozCraig 是的,刚刚检查了代码,存储在 vectorStorage 中的一些向量是空的。现在没有错误,但amplitudeVariable 现在总是以-1.07374e+08 出现。知道为什么吗? 哈哈。没有线索,初始化失败?但至少你知道为什么会出现无效的取消引用。很高兴你发现那个。顺便说一句,也许让你的装备上的复制缓冲区休息一下,并通过const 引用而不是值复制传递该向量。只是说... =P 祝你好运。 呃。 float amplitudeVariable 是按值传递的,您需要通过引用传递它,或者根本不传递它,只需将函数的返回值用作结果值。正如所写,您根本没有在amplitudeStorage[i] 中修改调用方的值。 @WhozCraig:虽然你的评论是正确的,但真的不需要“Duh”。 【参考方案1】:

您的编译器可能试图警告您,当amplitudeStorage 向量为空时,您无法正确引用amplitudeStorage[i] 的任何值。在开始时调整幅值存储的大小以匹配vectorStorage 的大小,或者使用push_back。我更喜欢push_back。这是一个完整的示例(它还避免了按值传递向量,并纠正了代码中使用int 来索引数据结构的问题,该数据结构的大小本身可以增长到超过int 可以容纳的最大值)。

请注意,此代码使用 C++11 编写,因为它使用基于范围的 for 循环。您可能需要告诉编译器打开对 C++11 的支持。 C++11 中有很多不错的便利。

#include <vector>
#include <algorithm>

using namespace std;

float WaveAmplitude(const vector<float>& dataVectorr) 
  return (*max_element(begin(dataVectorr), end(dataVectorr)))
    - (*min_element(begin(dataVectorr), end(dataVectorr)));


vector<float> amplitudeStorage;
vector<vector<float>> vectorStorage;    

int main(void) 
  // Populate vectorStorage somehow here, replacing this comment.
  amplitudeStorage.clear();
  for (const auto& wave : vectorStorage)
    
      amplitudeStorage.push_back(WaveAmplitude(wave));
    
  return 0;

【讨论】:

【参考方案2】:

我使用的一些向量是空的,这导致了错误。

【讨论】:

【参考方案3】:

查看完整的示例。我尝试co编译,没有问题。

#include <vector>
#include <algorithm>

using namespace std;

vector<float> amplitudeStorage;
vector< vector<float> > vectorStorage;

void AssignWaveAmplitude(float& amplitudeVariable, const vector<float>& dataVectorr) 
    if( dataVectorr.size() ) 
        amplitudeVariable = 0;
        return;
    
    amplitudeVariable = (*max_element(dataVectorr.begin(), dataVectorr.end())) - 
       (*min_element(dataVectorr.begin(), dataVectorr.end()));


main()

    for (int i = 0; i < amplitudeStorage.size(); i++) 
        AssignWaveAmplitude(amplitudeStorage[i], vectorStorage[i]);
    


【讨论】:

其实我想你会发现 std::begin 是完全有效的:en.cppreference.com/w/cpp/iterator/begin 也适用于数组! 是的,我找到了,但还没有修复答案 @fl-web 与你的回答我仍然得到同样的错误。 按值传递向量 似乎效率低下。使用 const 引用! 尝试在循环之前向 vectorStorage 添加一个元素。哎呀。对于这个版本的代码,您可能还应该使用amplitudeStorage.reserve(vectorStorage.size())。此外,您的代码中的 AssignWaveAmplitude 实际上并没有将任何内容分配给amplitudeStorage 中的相关条目,因为它是按值传递的。

以上是关于向量迭代器不可取消引用 C++的主要内容,如果未能解决你的问题,请参考以下文章

这段代码在哪里取消引用无效的迭代器? (C++)

C ++迭代器取消引用和前缀递增/递减样式? *--Iter ok 风格是不是明智?

输入迭代器是不是只能在赋值的右手符号上被取消引用?

C++中的向量迭代器

c++迭代器在迭代向量时崩溃

是否可以在 C++ 中使用转换迭代器?