STL vector和new运算符

STL Vectors and the new operator

本文关键字:运算符 new vector STL      更新时间:2023-10-16

这个问题应该很简单,也许很愚蠢,但是我就是找不到问题所在。

基本上,我必须用自然语言解析一些句子。我需要实现一个简单的算法来操纵"块"。一个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;
    }
}

代码编译,但是当我尝试使用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);,所以我认为这是由于新的操作符,但事实上调试器告诉我,我可以使用一个新的块;我不能做的是一个新的Block(a,b)(带参数构造函数)或设置数据…我觉得这很尴尬,因为每个文档都说=运算符已经重载了向量,所以它应该没有问题……再次为愚蠢的问题道歉,但我找不到它。: - (

每当您向V添加一个元素时,您也会增加j。这意味着j将始终等于V的长度。

这意味着下面的行将总是导致访问1超过V的结束。

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

稍后使用该值(当它是Blockp向量的一部分时)将导致各种各样的潜在问题。这可能是你的问题的根源。

同样,你有一个内存泄漏(你new,但没有delete)。在这里使用scoped_ptr,或者直接在堆栈上创建值。似乎没有理由把它分配到堆上。