2014-09-09 5 views
0

Я новичок в программировании и не могу решить следующую ошибку. Динамическая выделенная память кажется неисправной. Я уже пробовал google для людей с аналогичной проблемой.vector.push_back не удается выделить память

«Windows вызвало точку останова» в _CrtIsValidHeapPointer

Call Stack: 
msvrc110d.dll!_CrIsValidHeapPointer(const void* pUserData) Line 2036 
msvrc110d.dll!_free_dbg_nolock(void* pUserData, int nBlockUse) Line 1322 
msvrc110d.dll!_free_dbg(void* pUserData, int nBlockUse) Line 1265 
msvrc110d.dll!operator delete(void* pUserData) Line 54 
Editor.exe!std::allocator<CEditbox>::deallocate(CEditbox* _Ptr, unsigned int__formal) Line 586 
Editor.exe!std::_Wrap_alloc<<std::allocator<CEditbox> >::deallocate(CEditbox* _Ptr, unsigned int_Count) Line 888 
Editor.exe!std::vector<CEditbox,std::allocator<<CEditbox> >::_Reallocate(unsigned int_Count) Line 1518 
Editor.exe!std::vector<CEditbox,std::allocator<<CEditbox> >::_Reserve(unsigned int_Count) Line 1532 
Editor.exe!std::vector<CEditbox,std::allocator<<CEditbox> >::push_back(CEditbox&&_Val)Line 851 

Эта ошибка возникает, когда второй EditBox проталкивается к вектору. Мне очень странно, что когда я нажимаю 2 кнопки на вектор кнопок, ошибки не возникает, но класс кнопки почти такой же, как класс editbox.

Это кроме менеджера класса

CControls 

    std::vector<CEditbox> editboxes; 
    std::vector<CButton> buttons; 


CControls::CControls(sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow), am(paAm) { 
    activeControl = sf::Vector2i(0,0); 
} 


CControls::~CControls(void){ 
} 

void CControls::addEditbox(int paType, sf::Vector2i paPos){ 
    editboxes.push_back(CEditbox(paType, paPos, window, am)); 
} 

void CControls::addButton(int paType, sf::String paCaption,sf::Vector2i paPos){ 
    buttons.push_back(CButton(paType, paCaption, paPos, window,am)); 
} 

Эти 2 другие классы

CEditbox::CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow), font(paAm.getFont()), line(sf::RectangleShape(sf::Vector2f(2, 20))){ 
    active = false; 
    visible = false; 
    pos = paPos; 

    switch(paType){//templates for editboxes 
     case 1: 
      maxChar = 4; 
      sprite.setTexture(paAm.getTexture(2)); 
      sprite.setTextureRect(paAm.getTextureRect(209)); 

      text.setFont(font); 
      text.setCharacterSize(20); 
      text.setPosition(paPos.x + 5, paPos.y + 5); 
      text.setColor(sf::Color::Black); 

      line.setPosition(pos.x + 5, pos.y + 8); 
      line.setFillColor(sf::Color::Black); 
      break; 
     case 2: 
      maxChar = 20; 
      sprite.setTexture(paAm.getTexture(2)); 
      sprite.setTextureRect(paAm.getTextureRect(210)); 

      text.setFont(font); 
      text.setCharacterSize(20); 
      text.setPosition(paPos.x + 5, paPos.y + 5); 
      text.setColor(sf::Color::Black); 

      line.setPosition(pos.x + 5, pos.y + 8); 
      line.setFillColor(sf::Color::Black); 
      break; 
    } 

    text.setString(sf::String("")); 

    sprite.setPosition(pos.x, pos.y); 
    size = sf::Vector2i(sprite.getTextureRect().width, sprite.getTextureRect().height); 
} 

CEditbox::~CEditbox(void){ 

} 


void CEditbox::draw(){ 
    window.draw(sprite); 
    if(active){ 
     window.draw(line); 
    } 

    if(text.getString() != ""){ 
     window.draw(text); 
    } 
} 

bool CEditbox::inBounds(sf::Vector2i paPos){ 
    if(paPos.x > pos.x && paPos.y > pos.y && paPos.x < pos.x + size.x && paPos.y < pos.y + size.y){ 
     return true; 
    }else{ 
     return false; 
    } 
} 

void CEditbox::setVisible(bool paVisible){ 
    visible = paVisible; 
} 

bool CEditbox::isVisible(){ 
    return visible; 
} 

void CEditbox::setText(std::string paText){ 
    text.setString(paText); 
    line.setPosition(pos.x + text.getLocalBounds().width + 5, pos.y + 8); 
} 

void CEditbox::setActive(bool paActive){ 
    active = paActive; 
} 

bool CEditbox::hasMaxChar(){ 
    if(text.getString().getSize() >= 4){ 
     return true; 
    }else{ 
     return false; 
    } 
} 


CButton::CButton(int paType, sf::String paCaption,sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm) : window(paWindow), font(paAm.getFont()){ 
    hover = false; 
    visible = false; 
    clicked = false; 
    pos = paPos; 

    switch(paType){//templates for buttons 
     case 1: 
      sprite.setTexture(paAm.getTexture(2)); 
      sprite.setTextureRect(paAm.getTextureRect(206)); 
      spriteHover.setTexture(paAm.getTexture(2)); 
      spriteHover.setTextureRect(paAm.getTextureRect(207)); 
      spriteClick.setTexture(paAm.getTexture(2)); 
      spriteClick.setTextureRect(paAm.getTextureRect(208)); 

      text.setFont(font); 
      text.setCharacterSize(20); 
      text.setColor(sf::Color::Black); 
      break; 
     case 2: 
      sprite.setTexture(paAm.getTexture(2)); 
      sprite.setTextureRect(paAm.getTextureRect(203)); 
      spriteHover.setTexture(paAm.getTexture(2)); 
      spriteHover.setTextureRect(paAm.getTextureRect(204)); 
      spriteClick.setTexture(paAm.getTexture(2)); 
      spriteClick.setTextureRect(paAm.getTextureRect(205)); 

      text.setFont(font); 
      text.setCharacterSize(20); 
      text.setColor(sf::Color::Black); 
    } 

    text.setString(paCaption); 
    sprite.setPosition(pos.x, pos.y); 
    spriteHover.setPosition(pos.x, pos.y); 
    spriteClick.setPosition(pos.x, pos.y); 
    size = sf::Vector2i(sprite.getTextureRect().width, sprite.getTextureRect().height); 

    //center alignment 
    sf::FloatRect textRect = text.getLocalBounds(); 
    text.setOrigin(textRect.left + textRect.width/2.0f, textRect.top + textRect.height/2.0f); 
    text.setPosition((float)(pos.x + (size.x/2)), (float)(pos.y + (size.y/2))); 
} 


CButton::~CButton(void){ 
} 

void CButton::draw(){ 
    if(clicked){ 
     window.draw(spriteClick); 
     if(clickedFrames == 0){ 
      clicked = false; 
     }else{ 
      clickedFrames -= 1; 
     }  
    }else{ 
     if(hover){ 
      window.draw(spriteHover); 
     }else{ 
      window.draw(sprite); 
     } 
    } 


    if(text.getString() != ""){ 
     window.draw(text); 
    } 
} 

bool CButton::inBounds(sf::Vector2i paPos){ 
    if(paPos.x > pos.x && paPos.y > pos.y && paPos.x < pos.x + size.x && paPos.y < pos.y + size.y){ 
     return true; 
    }else{ 
     return false; 
    } 
} 

void CButton::setVisible(bool paVisible){ 
    visible = paVisible; 
} 

bool CButton::isVisible(){ 
    return visible; 
} 

void CButton::setText(std::string paText){ 
    text.setString(paText); 
} 

void CButton::setHover(bool paHover){ 
    hover = paHover; 
} 

void CButton::click(){ 
    clicked = true; 
    clickedFrames = 400; 
} 

Im используя копировальную-конструктор по умолчанию.

Я могу предотвратить сбой программы, если я делаю «editboxes.reserve (editboxes.size() + 2);» прежде чем нажимать объект на вектор, +1 не поможет.

В чем причина этой ошибки? (СРЮ для нечистой кода)

редактировать: определение EditBox

#pragma once 

#include <SFML/Graphics.hpp> 

#include "assetmanager.hpp" 


class CEditbox { 
public: 
    CEditbox(int paType, sf::Vector2i paPos, sf::RenderWindow& paWindow, CAssetmanager& paAm); 
    ~CEditbox(void); 

    void draw(); 
    bool inBounds(sf::Vector2i paPos); 
    void setVisible(bool paVisible); 
    bool isVisible(); 
    void setText(std::string paText); 
    void setActive(bool paActive); 
    bool hasMaxChar(); 

private: 
    sf::Vector2i pos; 
    sf::Font& font; 
    sf::Text text; 

    sf::Sprite sprite; 
    sf::Vector2i size; 

    int maxChar; 

    bool visible; 
    bool active; 

    sf::RenderWindow& window; 
    sf::RectangleShape line; 
}; 
+0

Можете ли вы опубликовать определение класса вашего 'CEditbox'? Проблема возникает, когда вектор должен изменить размер, чтобы содержать больше элементов. Я бы рискнул предположить, что это сценарий с двойным удалением. – Velox

ответ

3

Проблема не vector. Проблема заключается в классах и типах, которые вы храните в vector.

Если вы хотите сохранить тип в std::vector, ваше требование состоит в том, чтобы тип имел правильную семантику копирования. Другими словами, если возникла проблема при создании и уничтожении копий CEditbox, то проблема с vector.

Например, работает ли этот код правильно?

int main() 
{ 
    CEditbox e1(/* construct one */); 
    // fill e1 with some information (not shown) 
    //.. 
    CEditbox e2 = e1; 
    CEditbox e3(/*fill with parameters*/); 
    e3 = e1; 
} 

Если эта программа вызывает проблемы, то вы не можете хранить CEditbox в векторе. Программа выше должна быть в состоянии копировать, передавать, и не уничтожить все три экземпляра CEditbox без проблем (нет двойных удалений, никаких утечек памяти и т.д.)

Я вижу, что эта ссылка: http://sfml-dev.org/documentation/2.0/classsf_1_1Sprite.php описывает sf::Sprite класса , У вас есть экземпляры sf::Sprite в вашем классе CEditbox, и нигде в описании sf::Sprite не упоминается, что он может быть скопирован без проблем. Так что прямо здесь, вы можете быть в беде.

Если приведенный выше пример не работает должным образом, я предлагаю вам использовать std::vector<std::unique_ptr<CEditbox>> или std::vector<std::shared_ptr<CEditbox>> - другими словами, интеллектуальные указатели на ваш CEditbox.

+0

Я считаю, что должно быть нормально копировать 'sf :: спрайт'. SFML - хорошая библиотека, и вы не должны копировать что-то, что не поддерживает его. –

+0

FYI в C++ 11, требования для 'vector' во многих случаях были смягчены с помощью семантики перемещения. Можно создать «вектор» объектов только для перемещения. Если невозможно добавить в move-semantics значение 'CEditbox', то предложение этого ответа использовать' unique_ptr' или 'shared_ptr' является подходящим. –

+0

@Insilico: Верно, но если его класс не поддерживает копию, он должен удалить конструктор копирования и оператор =. –

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