C ++ - 矢量push_back()在fgets()之后不起作用

时间:2012-11-02 06:07:02

标签: c++ vector codeblocks

我在Windows 7上使用Code :: Blocks with MinGW;

我有这个功能正常:

Hueso* getSkel(int cual)
{
    unsigned int cont; //SkelCargados and CantSkel are global vectors
    for (cont =0; cont < SkelCargados.size();cont++) if ( CantSkel[cont] == cual) break; // EDIT: I changed <= with < before SkelCargados.size()
    if (SkelCargados.empty() || cont>SkelCargados.size())
    {
        char linea[LINEA]; //LINEA is a macro. Max value for this string.
        FILE * f = fopen("esqueletos.txt","rt");
        if (f == NULL) return NULL;
        fgets (linea,LINEA,f);

        vector<float> puntos_; // <-- please pay attention in these 4 lines
        puntos_.push_back(2.2);
        puntos_.push_back(2.2);
        puntos_.push_back(2.2);

        while (!feof(f))
        {
            //...
        }
        fclose(f);
    }
    return SkelCargados[CantSkel[cont]];
}

这一次,在尝试第二次推回时崩溃了。 (NOT)有趣的是,当我在fgets之前放置向量及其push_back()时,它表现正常。

编辑:如果我将向量声明为全局变量,它也能正常工作。

bool CargarMapa()
{
    char linea[LINEA];
    FILE * f = fopen("mapas.txt","rt");
    if (f == NULL) return false;
    fgets (linea,LINEA,f);


    vector<float> puntos_;
    puntos_.push_back(2.2);
    puntos_.push_back(3); //Here it crashes
    puntos_.push_back(4.2);


    while (!feof(f))
    {
        //...
    }
    fclose(f);
    return true;
}

崩溃时会发生这种情况:调试器抛出“程序接收信号SIGSEGV,分段错误。”并转到文件“new_allocator”中标有“HERE IT STOPS”注释的行.H“:

//(I did not write the following comment)

/*
 @brief  An allocator that uses global new, as per [20.4].
 @ingroup allocators

 This is precisely the allocator defined in the C++ Standard. 
   - all allocation calls operator new
   - all deallocation calls operator delete
*/
template<typename _Tp>
class new_allocator
{
public:
  typedef size_t     size_type;
  typedef ptrdiff_t  difference_type;
  typedef _Tp*       pointer;
  typedef const _Tp* const_pointer;
  typedef _Tp&       reference;
  typedef const _Tp& const_reference;
  typedef _Tp        value_type;

  template<typename _Tp1>
    struct rebind
    { typedef new_allocator<_Tp1> other; };

  new_allocator() throw() { }

  new_allocator(const new_allocator&) throw() { }

  template<typename _Tp1>
    new_allocator(const new_allocator<_Tp1>&) throw() { }

  ~new_allocator() throw() { }

  pointer
  address(reference __x) const { return std::__addressof(__x); }

  const_pointer
  address(const_reference __x) const { return std::__addressof(__x); }

  // NB: __n is permitted to be 0.  The C++ standard says nothing
  // about what the return value is when __n == 0.
  pointer
  allocate(size_type __n, const void* = 0)
  { 
if (__n > this->max_size())
  std::__throw_bad_alloc();

return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp))); //HERE IT STOPS
  }

请帮帮我。 :(

2 个答案:

答案 0 :(得分:3)

for (cont =0; cont<=SkelCargados.size();cont++) if ( CantSkel[cont] == cual) break;

不是你想要的。您可能希望在循环终止条件中使用比较运算符<而不是<=。如上所述,如果该向量中有一个项目,您可能最终break索引为1,这会导致您尝试索引到向量中的1位置只有一个位置。 (请记住,向量,数组和其他类似结构是零索引的,因此[0]是第一个元素,[1]是第二个元素,等等。)

最有可能的错误不在于push_back它实际上对你失败的地方,而在于你损坏内存的代码中的其他地方(导致未定义的行为)。

答案 1 :(得分:0)

<=看起来不正确

for (cont =0; cont<=SkelCargados.size();cont++) 
    if ( CantSkel[cont] == cual) break;

我认为应该是:

for (cont =0; cont<SkelCargados.size();cont++) 
    if ( CantSkel[cont] == cual) break;

也确保

return SkelCargados[CantSkel[cont]];

contCantSkel[cont]具有有效值。

小贴士:使用at()代替[],如果索引错误,您将获得out_of_range异常,让您更容易看到..