关闭 sf::RenderWindow 后检测到堆栈粉碎
Stack smashing detected after closing the sf::RenderWindow
我正在编写我的第一个 chip8 解释器和多线程程序,并遇到了这个问题:一旦我关闭窗口,我就会检测到堆栈粉碎。我已经检查代码很长时间了,但我找不到问题。真的很想得到一些帮助或建议。
模拟器.hpp
#ifndef CHEAP8_SRC_EMULATOR_HPP
#define CHEAP8_SRC_EMULATOR_HPP
#include "chip8.hpp"
#include "ui-settings.hpp"
#include <SFML/Graphics.hpp>
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#ifdef _WIN32
#define OS_PATH_SEP ''
#else
#define OS_PATH_SEP '/'
#endif
class Emulator
{
//misc
const std::string gamePath;
const std::string gameTitle;
//emulator
unsigned char memory[chip8::kMemSize] = {0};
//flags
bool gameLoaded = false;
std::atomic<bool> gameRunning{false};
//ui
const double kPixelSize = 12.5;
std::shared_ptr<sf::RenderWindow> window;
const UiSettings uiSettings;
//threading
std::thread uiThread;
std::mutex mutex;
void loadGame();
void loadFonts();
public:
explicit Emulator(char*);
~Emulator();
void run();
};
#endif //CHEAP8_SRC_EMULATOR_HPP
模拟器.cpp
#include "emulator.hpp"
#include <chrono> //================
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void launchUi(std::shared_ptr<sf::RenderWindow> window,
const UiSettings& uiSettings,
std::atomic<bool>& gameRunning)
{
window = std::make_shared<sf::RenderWindow>();
window->create(sf::VideoMode(uiSettings.width, uiSettings.height),
uiSettings.title,
sf::Style::Titlebar | sf::Style::Close);
window->setVerticalSyncEnabled(true);
window->setKeyRepeatEnabled(false);
const auto screenParams = sf::VideoMode::getDesktopMode();
window->setPosition(sf::Vector2i(screenParams.width / 2 - uiSettings.width / 2,
screenParams.height / 2 - uiSettings.height / 2));
sf::Event event;
while (window->isOpen()) {
while (window->pollEvent(event)) {
switch (event.type) {
case sf::Event::Closed:
window->close();
gameRunning.store(false);
break;
default:
break;
}
}
}
}
Emulator::Emulator(char* path)
: gamePath(path),
gameTitle(gamePath.substr(gamePath.find_last_of(OS_PATH_SEP) + 1)),
uiSettings(kPixelSize, chip8::kScreenWidth, chip8::kScreenHeight, gameTitle),
uiThread(launchUi, window, std::ref(uiSettings), std::ref(gameRunning))
{
loadGame();
loadFonts();
}
Emulator::~Emulator()
{
uiThread.join();
}
void Emulator::loadGame()
{
std::ifstream file(gamePath, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Couldn't open the game." << std::endl;
return;
}
std::vector<unsigned char> gameData;
gameData.insert(gameData.begin(),
std::istream_iterator<unsigned char>(file),
std::istream_iterator<unsigned char>());
if (gameData.size() > chip8::kAllowedGameSize) {
std::cerr << "The game is too big to fit into memory." << std::endl;
return;
}
for (size_t i = 0; i < gameData.size(); ++i) {
memory[i + chip8::kMemStart] = gameData[i];
}
gameLoaded = true;
std::cout << "Game loaded. Size: " << gameData.size() << 'n';
}
void Emulator::loadFonts()
{
for (int i = 0; i < chip8::kFontsetSize; ++i) {
memory[i] = chip8::kFontset[i];
}
std::cout << "Fontset loaded." << 'n';
}
void Emulator::run()
{
if (!gameLoaded) {
return;
}
gameRunning.store(true);
while (gameRunning.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
编辑:
#include "emulator.hpp"
#include <iostream>
int main(int argc, char *argv[])
{
if (argc != 2) {
std::cerr << "Usage: ./" << OS_PATH_SEP << "cheap8 game." << std::endl;
return 1;
}
Emulator emu(argv[1]);
emu.run();
return 0;
}
您的 Emulator
实例是在堆栈上创建的,因此它将使用足以存储其所有成员变量的堆栈空间。
这个很大:
unsigned char memory[chip8::kMemSize] = {0};
您可以将其更改为 std::vector
,以便它将数据存储在堆上,并且类实例仅包含元数据(大小、指向数据的指针(。
它还将改变对memory
数组的越界访问的效果 - 而不是弄乱堆栈和更改返回地址等内容,任何损坏都将对纯数据对象进行。
为了确保没有越界访问,您可以使用 vector 的 at()
成员函数。
相关文章:
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 堆栈和队列是否像C++中的数组一样传递?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 堆栈中大小变量输入错误 (C++)
- 堆栈问题(平衡表达式问题集)
- C++ 在堆栈中包含多态属性的类对象存储
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 在 C++ 中使用链表进行堆栈
- 变量周围的堆栈'...'已损坏
- 在 gtest 中初始化堆栈上的引用变量的隔离错误
- 关闭 sf::RenderWindow 后检测到堆栈粉碎