LIST_ENTRY 已损坏(即双重删除)。不知道为啥
Posted
技术标签:
【中文标题】LIST_ENTRY 已损坏(即双重删除)。不知道为啥【英文标题】:A LIST_ENTRY has been corrupted (i.e. double remove). No clue whyLIST_ENTRY 已损坏(即双重删除)。不知道为什么 【发布时间】:2018-03-29 21:09:25 【问题描述】:我正在使用来自 youtuber JavidX9 的一些技巧在控制台中制作一个简单的游戏。当窗口和缓冲区大小正确时,一切都会正确显示,仅供尝试运行它的任何人参考。当我在调试应用程序时尝试关闭应用程序时,我的问题就出现了。有时,如果我通过在屏幕上随机移动角色来弄乱它,它就会坏掉。我得到的错误是标题中列出的错误。但在那之后,我收到一个链接器错误,告诉我该进程仍在运行(我找不到)。所以调试是一场噩梦。我这几天一直在寻找这个问题的答案,希望你们中的一位 C++ 大神可以帮助我。代码很短。
编辑:刚刚发现了一些新信息。如果我启动程序,并且什么都不做,它会在大约一分钟左右后崩溃。潜在的线程问题?
#include <iostream>
#include <Windows.h>
#include <chrono>
using namespace std;
int screenWidth = 120; //Console Screen Size. X = Cols & Y = Rows
int screenHeight = 40;
int mapWidth = 48; //World Dimensions
int mapHeight = 48;
int playerX = mapWidth / 2;
int playerY = mapHeight / 2;
int main()
wchar_t *screen = new wchar_t[screenWidth * screenHeight];
HANDLE consoleHandle = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(consoleHandle);
DWORD bytesWritten = 0;
// 16 x 3
wstring map; //^
map += L"################################################";
map += L"#..............................................#";
map += L"#.......########........########........########";
map += L"#..............#...............#...............#";
map += L"#......##......#.......##......#.......##......#";
map += L"#......##......#.......##......#.......##......#";
map += L"#..............#...............#...............#";
map += L"###............#.##............#.##............#";
map += L"##.............#.#.............#.#.............#";
map += L"#......####..###.......####..###.......####..###";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#..............#...............#...............#";
map += L"#......#########.......#########.......#########";
map += L"#..............#...............................#";
map += L"#..............................................#";
map += L"#..............................................#";
map += L"#..............................................#";
map += L"#.......########........########........########";
map += L"#..............#...............#...............#";
map += L"#......##......#.......##......#.......##......#";
map += L"#......##......#.......##......#.......##......#";
map += L"#..............#...............#...............#";
map += L"###............#.##............#.##............#";
map += L"##.............#.#.............#.#.............#";
map += L"#......####..###.......####..###.......####..###";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#..............#...............#...............#";
map += L"#......#########.......#########.......#########";
map += L"#..............#...............................#";
map += L"#..............................................#";
map += L"#..............................................#";
map += L"#..............................................#";
map += L"#.......########........########........########";
map += L"#..............#...............#...............#";
map += L"#......##......#.......##......#.......##......#";
map += L"#......##......#.......##......#.......##......#";
map += L"#..............#...............#...............#";
map += L"###............#.##............#.##............#";
map += L"##.............#.#.............#.#.............#";
map += L"#......####..###.......####..###.......####..###";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#......#.......#.......#.......#.......#.......#";
map += L"#..............#...............#...............#";
map += L"#......#########.......#########.......#########";
map += L"#..............#...............................#";
map += L"################################################";
const int TICKS_PER_SECOND = 20;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;
DWORD next_game_tick = GetTickCount();
int loops;
bool game_is_running = true;
while (game_is_running)
loops = 0;
while (GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP)
// Update
for (int i = 0; i < screenWidth * screenHeight; i++)
screen[i] = ' ';
if (GetAsyncKeyState((unsigned short)'A'))
if (map[(playerX - 1) + mapWidth * playerY] == '#')
break;
else
playerX--;
if (GetAsyncKeyState((unsigned short)'D'))
if (map[(playerX + 1) + mapWidth * playerY] == '#')
break;
else
playerX++;
if (GetAsyncKeyState((unsigned short)'S'))
if (map[playerX + mapWidth * (playerY + 1)] == '#')
break;
else
playerY++;
if (GetAsyncKeyState((unsigned short)'W'))
if (map[playerX + mapWidth * (playerY - 1)] == '#')
break;
else
playerY--;
next_game_tick += SKIP_TICKS;
loops++;
// Draw the map to the buffer
for (int y = 0; y < mapHeight; y++)
for (int x = 0; x < mapWidth; x++)
screen[x + screenWidth * y] = map[x + mapWidth * y];
screen[playerX + screenWidth * playerY] = '@'; // Draw the player
// Display the Buffer
screen[screenWidth * screenHeight - 1] = '\0';
WriteConsoleOutputCharacter(consoleHandle, screen, screenWidth * screenHeight, 0,0 , &bytesWritten);
【问题讨论】:
map
对于使用命名空间 std 的人来说是一个危险的变量名称。
你是对的。没有考虑它,因为我正在做这个来测试一些东西。我会改变的。谢谢。
@scohe001 仅当他们没有练习安全的 c++ 时;永远不要让你的std
s 出去。
您可以首先验证您是否正在访问map
字符串范围之外的元素。您可以通过使用at()
访问元素来做到这一点。也可以使用std::vector
而不是new/delete
——然后您可以使用与at
调用相同的技术。
@PaulMcKenzie 谢谢,我试一试。希望我可以正确地实现它,但我也开始怀疑它是否与线程有关(请参阅原始帖子上的编辑)。在我的不和谐聊天中有人提到,我没有线程经验。你有没有看到任何会导致线程问题的东西?
【参考方案1】:
我解决了这个问题。我的地图阵列比我的屏幕阵列大,导致了这个问题。我无法深入解释这是如何导致错误的,但确实如此。添加 2d 相机后,将其锁定到玩家坐标,并将其夹在地图数组的边界上,它现在可以正常工作了。我现在还有一整套其他问题要处理,但这一个可以标记为已解决。如果其他人可以解释为什么这是一个令人惊讶的问题的深层原因。谢谢。
【讨论】:
以上是关于LIST_ENTRY 已损坏(即双重删除)。不知道为啥的主要内容,如果未能解决你的问题,请参考以下文章
在向量中使用擦除时双重释放或损坏(fasttop)。知道它们的索引,你怎么能擦除向量的几个项目?