2011-11-26 69 views
4

這個問題應該很簡單,也許很愚蠢,但我找不到問題。STL Vectors and the new operator

基本上,我必須用自然語言解析一些句子。我需要實現一個操縱「塊」的簡單算法。一個Block由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; 
    } 
} 

代碼編譯,但是當我嘗試從模塊使用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)(帶參數構造函數)或設置數據...我覺得這很尷尬,因爲每個文檔都說=運算符已經爲矢量重載,所以它應該沒有問題...對不起,我再也找不到它了。:-(

+0

這怎麼可能編譯?我找不到類聲明的結尾,也找不到SetData。 – Lou

+1

你可以格式化你的代碼嗎?不要使用標籤,只能使用空格。縮進和空白將不勝感激。 –

+0

對不起,我沒有粘貼setData方法,我以爲我有。我現在格式化它 – Tex

回答

2

每當您將元素添加到V時,您也會增加j。這意味着j將始終等於V的長度。

這意味着下面一行將會是總是導致訪問1過去了V的末尾。

Blbl->setData(V[j-1], V[j]); 

後使用該值(當它成爲一個Blockp載體將導致潛在的問題,所有的方式的一部分,這可能是你的問題的根源。

而且,你有內存泄漏(你new ed,但沒有delete)。在這裏使用scoped_ptr,或者只是在堆棧上創建值。似乎沒有理由將其分配到堆上。

+0

它的工作,太棒了!我覺得這很愚蠢,謝謝! – Tex