2012-11-02 3 views
0

Я работаю с кодом :: Блоки с MinGW в Windows 7;C++ - вектор push_back() не работает после fgets()

У меня есть эта функция, которая работает отлично:

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

И этот, что сбой при попытке 2-й push_back. Смешная вещь (НЕ) заключается в том, что когда я помещаю вектор и его push_back() s перед fgets, он ведет себя нормально.

EDIT: Если я объявляю вектор глобальной переменной, он отлично работает.

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, неисправность Сегментация.» и переходит к строке, помеченной с «ЗДЕСЬ IT упорами» комментарий, в файле «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 
    } 

Пожалуйста, помогите мне. :(

+0

Я предполагаю, что это вопрос типа, попробуйте 'puntos_.push_back (3.0);' – Terkel

+2

@Simon Банг Terkildsen это не проблема –

+0

@DenisErmolin хорошо рад, что я не ставил на него деньги тогда :) – Terkel

ответ

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

не то, что вы хотите. Вероятно, вы хотели использовать оператор сравнения < вместо <= в состоянии завершения цикла. Как написано, если в этом векторе есть один элемент, вы можете положить break ing на индекс 1, что приведет к попытке индексации в позицию 1 в векторе, который имеет только одну позицию. (Помните, что векторы, массивы и другие подобные конструкции имеют нулевой индекс, поэтому [0] является первым элементом, [1] является вторым, и т.д.)

Скорее всего, ошибка кроется не в push_back, где он на самом деле терпит неудачу для вас , но где-то еще в коде, где вы испортили память (что приводит к неопределенному поведению).

+0

Да, это, вероятно, поскользнулся. Во всяком случае, я сделал это изменение, но он все еще падает. О, я забыл еще одну забавную вещь, я сразу же отредактирую. – Umagon

+0

@Umagon: Тогда это соответствует тому, что я сказал. Когда у вас есть повреждение памяти, авария часто будет далека от причины сбоя. Где бы ни была проблема, крайне маловероятно, чтобы эта проблема была в 'std :: vector :: push_back'. –

+0

Да, я думаю, вы правы. Я сделаю глубокую проверку. – Umagon

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

что cont и CantSkel[cont] имеют действительный

совет: использовать at() вместо [], то вы получите out_of_range исключение, если индекс является неправильным, делает его легче увидеть ..

+0

Хорошо, я нахожусь на этом, спасибо. Однако эта функция не сработает. Любые мысли о втором ...? Также спасибо за подсказку. – Umagon

Смежные вопросы