简体   繁体   中英

C++ - vector push_back() not working after fgets()

I'm working with Code::Blocks with MinGW on Windows 7;

I have this function that works fine:

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]];
}

And this one, that crashes while trying the 2nd push_back. The (NOT)funny thing is that when I put the vector and its push_back()s before fgets, it behaves normally.

EDIT: If I declare the vector as global variable it works fine too.

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;
}

This is what happens when it crashes: The debugger throws "Program received signal SIGSEGV, Segmentation fault." and goes to the line marked with a "HERE IT STOPS" comment, in file "new_allocator.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
  }

Please, help me. :(

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

is not what you want. You probably wanted to use the comparison operator < instead of <= in your loop termination condition. As written, if there is one item in that vector, you might end up break ing on an index of 1 , which would result in you trying to index to position 1 in the vector which only has one position. (Remember, vectors, arrays, and other similar constructs are zero-indexed, so [0] is the first element, [1] is the second, etc.)

Most likely the bug lies not in the push_back where it actually fails for you, but somewhere else in the code where you corrupted memory (which results in undefined behavior).

The <= doesn't look right

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

i think it should be:

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

also make sure in

return SkelCargados[CantSkel[cont]];

that cont and CantSkel[cont] have valid values.

a tip: use at() instead of [] then you will get an out_of_range exception if the index is wrong, makes it easier to see..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM