C++ vector.push_back无法分配内存

C++ vector.push_back无法分配内存,c++,vector,push-back,C++,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.dl

我是编程新手,无法解决以下错误。动态分配的内存似乎有故障。我已经尝试用谷歌搜索有类似问题的人

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
将第二个编辑框推送到向量时,会发生此错误。我觉得很奇怪,当我将两个按钮按到按钮向量时,没有发生错误,但是button类与editbox类几乎相同

这是除manager类之外的其他类

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));
}
这是另外两门课

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;
}
我使用默认的复制构造函数

如果我使用editboxs.reserveeditboxes.size+2,我可以防止程序崩溃;在将对象推到向量之前,+1没有帮助

这一错误的原因可能是什么? 不洁代码的sry

编辑: 编辑框的定义

#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;
};
问题不是向量。问题是要存储在向量中的类和类型

当您希望将类型存储在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的所有三个实例,而不会发出任何双重删除、内存泄漏等问题

我看到这个链接: 描述sf::Sprite类。您的CEditbox类中有一个sf::Sprite的实例,在sf::Sprite的描述中没有提到可以毫无问题地复制它。所以就在那里,你可能会有麻烦

如果上面的样本不正确工作,那么我建议您考虑使用STD::vector或STD::vector——换句话说,智能指针指向SutiBox的 问题不是向量。问题是要存储在向量中的类和类型

当您希望将类型存储在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的所有三个实例,而不会发出任何双重删除、内存泄漏等问题

我看到这个链接: 描述sf::Sprite类。您的CEditbox类中有一个sf::Sprite的实例,在sf::Sprite的描述中没有提到可以毫无问题地复制它。所以就在那里,你可能会有麻烦


如果上面的样本不正确工作,那么我建议您考虑使用STD::vector或STD::vector——换句话说,智能指针指向SutiBox的 你能发布你的CEditbox的类定义吗?当向量必须调整大小以容纳更多项时,问题似乎会发生。我猜这是一个双重删除的场景。你能发布你的CEditbox的类定义吗?当向量必须调整大小以容纳更多项时,问题似乎会发生。我冒昧地猜测这是一个双删除场景。我相信复制一个sf::sprite应该是可以的。SFML是一个很好的库,不应该让您复制不支持它的东西。仅供参考,在C++11中,在许多情况下,使用移动语义可以放宽对向量的要求。可以创建仅移动对象的向量。如果无法将移动语义添加到CEditbox中,则此答案建议使用unique_ptr或shared_ptr是合适的。@Insilico:True但如果他的类不支持复制,则应删除复制构造函数和运算符=。@NeilKirk-我在此处查看了sf::sprite标题:有一个指针成员,所以我不知道复制是否安全。精灵有一个指向外部纹理资源的指针,必须单独管理。我相信复制sf::sprite应该可以。SFML是一个很好的库,不应该让您复制不支持它的东西。仅供参考,在C++11中,在许多情况下,使用移动语义可以放宽对向量的要求。可以创建仅移动对象的向量。如果无法将移动语义添加到CEditbox中,则此答案建议使用unique_ptr或shared_ptr是合适的。@Insilico:True但如果他的类不支持复制,则应删除复制构造函数和运算符=。@NeilKirk-我在此处查看了sf::sprite标题:有一个指针成员,所以我不知道复制是否安全。精灵有一个指向外部纹理资源的指针,必须单独管理。