次のコードは、の "iterator + offset is not range"と表示された場所にアサートします。std :: vectorの奇妙な動作back()
void Network::PushInput(int c, int h, int w) {
Input* input = new Input(batch, c, h, w, data);
layers.push_back(input); // this happens to be the first push_back()
// layers.push_back(input); // doing another doesn't change the assert!
Layer *foo = layers.back(); // asserts here
Layer *baz = layers[layers.size()-1]; // does not assert
}
入力はLayerのパブリックサブクラスです。層は、私は、例えば、int型*、より多くのバニラテンプレートタイプで上記を複製しようとした場合)(バック、
std::vector<Layer *>layers;
として宣言されていないと主張する期待どおりに動作されます。どういうわけか、テンプレートタイプがここで重要です。 (注:_ITERATOR_DEBUG_LEVELは2で、これはベクトルクラスのアサーションチェックをトリガーします)
コード内のback()のすべてをsize() - 1に変更するのではなくむしろここで何が起こっているのか理解する。
アイデア? (私はこの問題の原因を突き止めるまでコードを混乱させるでしょうが、うまくいけば他の人には分かります)
(私はVisual Studio 2013 Community Editionを使用しています)
#include <vector>
using namespace std;
namespace layer {
class Layer {
public:
Layer(float alpha = 0, float momentum = 0.9f, float weight_decay = 0);
virtual ~Layer();
// three virtual method that all layers should have
virtual void forward(bool train = true) = 0;
virtual void backward() = 0;
virtual void update() = 0;
void adjust_learning(float scale); // change the learning rate
Layer* prev; // previous layer
Layer* next; // next layer
float* data; // X': output (cuDNN y)
int batch; // n: batch size
float alpha; // learning rate
float momentum; // beta: momentum of gradient
float weight_decay; // gamma: weight decay rate
};
} /* namespace layer */
namespace layer {
Layer::Layer(float alpha_, float momentum_, float weight_decay_)
{
std::memset(this, 0, sizeof(*this));
alpha = alpha_;
momentum = momentum_;
weight_decay = weight_decay_;
}
Layer::~Layer() {}
void Layer::adjust_learning(float scale) {
alpha *= scale;
}
}
namespace layer {
class Input : public Layer {
public:
Input(int n, int c, int h, int w, float* _data);
virtual ~Input();
void forward(bool train = true);
void backward();
void update();
};
}
namespace layer {
Input::Input(int n, int c, int h, int w, float* _data) : Layer() {
prev = NULL;
batch = n;
data = _data;
}
Input::~Input() {
data = NULL;
}
void Input::forward(bool train) {
// nothing
}
void Input::backward() {
// nothing
}
void Input::update() {
// nothing
}
}
using namespace layer;
namespace model {
class Network {
private:
std::vector<Layer*> layers; // list of layers
bool has_input, has_output; // sanity check
float* data; // input on device
int batch; // whole size of data, batch size
public:
Network(int batch_size);
virtual ~Network();
void PushInput(int c, int h, int w);
};
}
namespace model {
void Network::PushInput(int c, int h, int w) {
Input* input = new Input(batch, c, h, w, data);
layers.push_back(input);
Layer *foo = layers.back(); // **WHY DOES THIS ASSERT??**
}
Network::Network(int _batch) {
std::memset(this, 0, sizeof(*this));
batch = _batch;
}
Network::~Network() {
for (Layer* l : layers)
delete l;
}
}
void main()
{
model::Network foo(10);
foo.PushInput(2, 3, 4);
}
「ここにアサートする」とはどういう意味ですか?実際の診断とは何ですか?スタックトレースはありますか? –
このコードは、うまくいくはずです。 'push_back'と' back'呼び出しの間に何か起こっていることはありますか? [最小限の、完全で検証可能な例](http://stackoverflow.com/help/mcve)を作成してください。 –
私は最初の行にあるアサーションメッセージを強調しました。 –