看似不错的删除 [] 程序崩溃
Posted
技术标签:
【中文标题】看似不错的删除 [] 程序崩溃【英文标题】:Program crash on seemingly fine delete[] 【发布时间】:2019-05-21 16:07:21 【问题描述】:我正在使用 Visual C++ 2017 构建 OpenGL/GLFW 应用程序。但是,我在delete[]
语句上遇到了崩溃,并显示消息“HEAP CORRUPTION DETECTED : [...] CRT 检测到应用程序在堆缓冲区结束后写入内存。”在我写的以下函数中:
#include <direct.h>
void setwd(char **argv)
char *buf = new char[strlen(argv[0])];
strcpy(buf, argv[0]);
// Handle both possible separators
char *p = strrchr(buf, '/');
if(!p)
p = strrchr(buf, '\\');
if(p)
*(p + 1) = '\0';
_chdir(buf);
delete[] buf;
如果我删除对setwd
的呼叫,一切正常。我在调试时确保strlen(argv[0])
永远不会为0。
值得注意的是,如果使用 MSYS2/gcc 编译,这将完全正常。
【问题讨论】:
被一个错误关闭。缓冲区太小,无法容纳字符串。 减少您的缺陷数量并使用std::string
作为文本。 std::string
自动为您管理内存,并具有搜索和替换方法。
不要自己管理内存。把它留给底层结构的实现者。使用字符串/向量为您执行此操作。
【参考方案1】:
缓冲区中需要一个额外的字符,用于空终止符:new char[strlen(argv[0])+1]
【讨论】:
好吧,这行得通。愚蠢的错误,但为什么它在 MSYS 上运行良好,最重要的是,为什么要等到delete[]
运算符失败?这是超级误导。
@Matrefeytontias 这是未定义的行为,所以究竟会发生什么取决于您的实现的具体细节。在这种情况下,您的标准库的堆分配器可能会在从new
返回的每个内存块之后存储一些有用的东西(例如,分配的大小,或指向某些已分配对象列表中下一个内存块的指针),并且你覆盖了它。然后,当实现尝试读取此信息时,它会感到困惑。使用另一个工具链,您的新/删除实现可能会以不同的方式工作并且很好。
对我来说已经足够了。谢谢你的解释!
@Matrefeytontias 我赞同其他人的建议,即使用std::string
而不是原始字符数组。它们更容易正确使用而不会导致错误,主要是因为它们会自动管理自己的内存,而无需您担心。以上是关于看似不错的删除 [] 程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章
reloadRowsAtIndexPaths:withRowAnimation: 使我的应用程序崩溃
NSFetchedResultsController:删除 1 行使应用程序崩溃