我是编程新手,无法解决以下错误。动态分配的内存似乎有问题。我已经尝试过针对有类似问题的人进行谷歌搜索。
“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
将第二个编辑框推送到矢量时会发生此错误。我觉得很奇怪,当我按下2个按钮时,按钮矢量没有发生错误,但按钮类几乎与编辑框类相同。
除了经理类
之外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;
}
我正在使用默认的复制构造函数。
我可以阻止程序崩溃,如果我执行“editboxes.reserve(editboxes.size()+ 2);”在将对象推向矢量之前,+1不会有帮助。
出现此错误的原因是什么? (为不洁的代码而烦恼)
编辑: 编辑框的定义
#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 :(得分: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。