矢量对无效矢量<t>下标

时间:2017-10-26 18:40:33

标签: c++ vector

我对下面的代码有疑问。我的编译器告诉我,我有一个

 _Xout_of_range("invalid vector<T> subscript");

我一直在浏览所有代码,试图找出它的位置。我的教授说,它与我使用.size()有关,或者当我试图找到我的矢量大小时,我做了一些额外的事情,导致它超出界限。你们可以推荐一些建议吗?

//
//DiscreteDistribution.hpp
//

#ifndef _DISCRETE_DISTRIBUTION_GUARD
#define _DISCRETE_DISTRIBUTION_GUARD

#include <utility>
#include <vector>
#include <iostream>
#include <sstream>
#include <iomanip>

#include "Random.h"
#include "Types.h"

//Reference used: http://www.cplusplus.com/reference/utility/pair/

/*
// Map-based distribution <KEY, WEIGHT>
//     where the weight is cumulative (allowing random number generation)
//     to return the key value
*/
template<typename KEY_T>
class DiscreteDistribution
{
private:

    WEIGHT_T max() const
    {
        return _valueToWeightMap.back().second;
    }

public:
    DiscreteDistribution() :_valueToWeightMap{}, _rng{}
    {}

    DiscreteDistribution(const DiscreteDistribution<KEY_T>& orig) : _valueToWeightMap {orig._valueToWeightMap}
    {

    }

    const DiscreteDistribution& operator=(const DiscreteDistribution<KEY_T>& orig)
    {
        return orig;
    }

    virtual ~DiscreteDistribution()
    {
        _valueToWeightMap.clear();
    }

    /* @param key -- key value for mapping
    * @param weight -- weight of the particular key
    *    If the key is not in the distribution, add it, otherwise,
    * @throws std::string object for negative weights (when the @param weight is cast to a standard int)
    */

    void add(KEY_T key, WEIGHT_T weights)
    {
        WEIGHT_T delta = 0;

        bool keycheck = false;

        int index = -1;

        //Throw exception if weight below zero.
        if ( (int) weights < 0)
        {
            throw std::string("Warning::was this weight intended; Negative weight?");
        }

        //Check for existing pairs.
        for (int i = 0; i < _valueToWeightMap.size(); i++)
        {
            //If _vTwM index equals key. Set the index to 'i' and boolean to true.
            if (_valueToWeightMap.at(i).first == key)
            {
                index = i;
                keycheck = true;
            }
        }

        //If the index is less than zero...and there are no existing pairs.
        if (index < 0)
        {
            //And keycheck is true (see past evaluation above)...
            if (keycheck)   
            {
                //Get the max weight and set it to instance variable WEIGHT_T delta and add it to the 'weights' value
                //to get the new weight to add to the pair.
                delta = _valueToWeightMap.at(_valueToWeightMap.size()).second;
                weights += delta;
            }

            //New pair to push back.
            _valueToWeightMap.push_back(std::pair<KEY_T, WEIGHT_T> ( key, weights ));

        }
        else 
        {
            //Find the change in weight set to delta.
            delta = _valueToWeightMap.at(index).second - ((int) weights);

            //Loop through and find the change in weight at each 'i'.
            for (int i = index; i < _valueToWeightMap.size(); i++)
            {
                _valueToWeightMap.at(i).second -= delta;
            }
        }
    }

    /* @param key -- key value for mapping
    * @return the weight in the discrete distribution
    * Get the weight at the given key value.
    */

    WEIGHT_T weight(KEY_T key) const
    {   
        WEIGHT_T weightAtKey;

        for (int i = 0; i < _valueToWeightMap.size(); i++)
        {
            //if the key _value at the index i is equal to the key value being passed in...get it's weight (if it has one).
            if (_valueToWeightMap.at(i).first == key)
            {
                //Current minus the prev to get the weight difference.
                weightAtKey = _valueToWeightMap.at(i).second - _valueToWeightMap.at(i - 1).second;  
            }
        }
        return weightAtKey;
    }

    /*
    * Take the value(key) at whatever the index and divide that over the cumulative weight to find the
    * probability after adjusting for the difference.
    */
    double DiscreteDistribution::probability(KEY_T key) const
    {
        //Set the weight by finding the given key value's weight.
        double wgt = (double) weight(key);

        if (wgt != 0)
        {
            //Take the cumulative weight divided by the max to get probability.
            return  wgt / max();

        }
        return 0;
    }

    // @return Based on the given weights, roll a die to return the resulting key value
    // Use Random rng to find this.
    KEY_T operator()() const
    {
        //Find the cumulative weight between 1 and the max.
        int die = _rng.nextInt(1, max());

        //Loop through and compare weights and return the key that closely corresponds to the weight found.
        //Example <'A', 49>
        //        <'B', 40>
        //        <'C', 35>
        //Die roll is 45. Since 45 is less than the key value at 'A', it will not return' A', but instead,
        //Returns 'B' since it's the closest value to 45.

        for(std::pair<KEY_T, WEIGHT_T> pair : _valueToWeightMap)
        {
            if(die <= pair.second)
            {
                return pair.first;
            }
        }
        return 0;
    }


    // toString and overloaded output operator
    std::string toString() const;

    friend std::ostream& operator<<(std::ostream& os, const DiscreteDistribution& dis)
    {
        //Simply output the ToString.
        os << dis.toString();
        return os;
    }

protected:

    // Map of keys to cumulative weights
    std::vector<std::pair<KEY_T, WEIGHT_T> > _valueToWeightMap;

    // The random number generator
    Random _rng;

};

#endif

2 个答案:

答案 0 :(得分:2)

你的教授是对的。您无法在其size()索引向量,因为容器在C ++中是0索引的。

这超出范围:

_valueToWeightMap.at(_valueToWeightMap.size())

答案 1 :(得分:1)

您无法访问大小的矢量。罪魁祸首就是这条线

delta = _valueToWeightMap.at(_valueToWeightMap.size()).second;

如果您想访问最后一个元素,请执行此操作

delta = _valueToWeightMap.at(_valueToWeightMap.size() - 1).second;