STL Векторы и новый оператор
Этот вопрос должен быть довольно простым, возможно, глупым, но я просто не могу найти проблему.
По сути, я должен разобрать некоторые предложения на естественном языке. Мне нужно реализовать простой алгоритм, который манипулирует "блоками". Блок состоит из двух псевдосуждений, состоящих из 20 слов (строк).
Вот код:
typedef vector<string> Pseudosentence;
#define W 20 // A Pseudosentence is made of W words
#define K 2 // A block is made of K Pseudosentences
class Block {
public:
vector<Pseudosentence> p;
multimap<string, int> Scoremap;
Block() {
p.resize(2);
}
Block(Pseudosentence First, Pseudosentence Second){
p.resize(2);
p[0] = First;
p[1] = Second;
}
void rankTerms(); // Calculates some ranking function
void setData(Pseudosentence First, Pseudosentence Second){
p[0] = First;
p[1] = Second;
}
};
stringstream str(final); // Final contains the (preprocessed) text.
string t;
vector<Pseudosentence> V; // V[j][i]. Every V[j] is a pseudosentence. Every V[j][i] is a word (string).
vector<Block> Blocks;
vector<int> Score;
Pseudosentence Helper;
int i = 0;
int j = 0;
while (str) {
str >> t;
Helper.push_back(t);
i++;
//cout << Helper[i];
if (i == W) { // When I have a pseudosentence...
V.push_back(Helper);
j++; // This measures the j-th pseudosentence
Helper.clear();
}
if (i == K*W) {
V.push_back(Helper);
j++; // This measures the j-th pseudosentence
Helper.clear();
//for (int q=0; q < V.size(); ++q) {
//cout << "Cluster "<< q << ": \n";
//for (int y=0; y < V[q].size(); ++y) // This works
//cout << y <<": "<< V[q][y] << endl;
//}
Block* Blbl = new Block;
Blbl->setData(V[j-1], V[j]); // When I have K pseudosentences, I have a block.
cout << "B = " << Blbl->p[0][5]<< endl;
Blbl->rankterms(); // Assigning scores to words in a block
Blocks.push_back(*Blbl);
i = 0;
}
}
Код компилируется, но когда я пытаюсь использовать setData(a,b)
метод из блока, XCode приводит меня к stl_construct.h
и говорит мне, что он получил EXC_BAD_ACCESS
сигнал.
Код, к которому я обращен, таков:
/** @file stl_construct.h
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
#ifndef _STL_CONSTRUCT_H
#define _STL_CONSTRUCT_H 1
#include <bits/cpp_type_traits.h>
#include <new>
_GLIBCXX_BEGIN_NAMESPACE(std)
/**
* @if maint
* Constructs an object in existing memory by invoking an allocated
* object's constructor with an initializer.
* @endif
*/
template<typename _T1, typename _T2>
inline void
_Construct(_T1* __p, const _T2& __value)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 402. wrong new expression in [some_]allocator::construct
::new(static_cast<void*>(__p)) _T1(__value);
}
(Фактическая строка, которую выделяет XCode, это ::new(static_cast<void*>(__p)) _T1(__value);
поэтому я подумал, что это связано с новым оператором, но на самом деле отладчик показал мне, что я могу использовать новый блок; Что я не могу сделать, так это нового Block(a,b)
(с конструктором параметров) или настройкой данных... Я нахожу это неловким, потому что каждая документация говорит, что =
оператор был перегружен для векторов, поэтому проблем не должно быть... еще раз извините за глупый вопрос, но я не могу его найти.:-(
1 ответ
Каждый раз, когда вы добавляете элемент в V
Вы также увеличиваете j
, Это означает, что j
всегда будет равна длине V
,
Это означает, что строка ниже всегда будет иметь доступ 1 после конца V
,
Blbl->setData(V[j-1], V[j]);
Использование этого значения позже (когда оно является частью Block
"s p
вектор приведет к всевозможным потенциальным проблемам. Это, вероятно, источник вашей проблемы.
Кроме того, у вас есть утечка памяти (вы new
Эд, но не сделал delete
). Использовать scoped_ptr
здесь, или просто создайте значение в стеке. Кажется, нет причин выделять его в кучу.