这个问题应该很简单,也许是愚蠢但我找不到问题.
基本上,我必须用自然语言解析一些句子.我需要实现一个操作“块”的简单算法.块由2个伪句组成,由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; } }
代码编译,但是当我尝试使用Block的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);所以我认为这是由于new运算符,但事实上调试器向我显示我可以使用一个新的Block;我不能做的是一个新的Block(a,b)(带有参数构造函数)或设置数据……我发现这很尴尬,因为每个文档都说过=运算符已经过载了载体,所以应该没问题…对于这个愚蠢的问题再次抱歉,但我找不到它.:-(
解决方法
每次向V添加元素时,也会增加j.这意味着j将始终等于V的长度.
这意味着下面的行将始终导致访问1超过V的结尾.
Blbl->setData(V[j-1],V[j]);
稍后使用该值(当它作为Block的p向量的一部分时将导致各种潜在的问题.这可能是您的问题的根源.
此外,您有内存泄漏(您新增但未删除).在这里使用scoped_ptr,或者只在堆栈上创建值.似乎没有理由在堆上分配它.