内存博士和神秘的未初始化读取
Dr Memory and the mysterious uninitialized read
下面的代码没有做任何有趣的事情,但神秘的是为什么 Dr Memory 会认为存在单元化读取?有什么想法吗?
#include <memory>
int main(int argc, const char* argv[])
{
int aa[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::unique_ptr<int[]> p {new int[10]};
for (auto i = 0; i < 10; ++i) {
p[i] = aa[i];
}
return 0;
} // <-- Dr Memory says UNINITIALIZED READ here
编辑:这是完整的错误详细信息。
Error #1: UNINITIALIZED READ: reading 0x0028ff20-0x0028ff24 4 byte(s)
# 0 __mingw_glob [src/main.cpp:14]
# 1 _setargv [src/main.cpp:14]
# 2 __mingw_CRTStartup
# 3 mainCRTStartup
# 4 ntdll.dll!RtlInitializeExceptionChain +0x62 (0x772c8fe2 <ntdll.dll+0x38fe2>)
# 5 ntdll.dll!RtlInitializeExceptionChain +0x35 (0x772c8fb5 <ntdll.dll+0x38fb5>)
Note: @0:00:00.297 in thread 9780
Note: instruction: cmp (%esi) [=11=]x0040a11e
您的 main
函数中指示的行不是发生错误的行。如堆栈跟踪所示,错误发生在 __mingw_glob
中,并且发生在 在 调用任何代码之前。 (这是扩展命令行上传递的文件名通配符的函数。在 Linux 上,这项工作由 shell 完成,但在 Windows 上,它是 C 运行时的责任。)
换句话说,它出现在 mingw
库中。这很可能是无害的误报,您应该简单地添加一个排除项。
我认为 Dr Memory 可能错误地将其识别为未初始化,因为它在您的任何代码 运行 之前由操作系统初始化,或者在 DrMemory 初始化之前由 运行 的代码初始化,或者因为它被传递给了一个系统调用,该系统调用实际上并不读取内存而只写入内存。
为什么它在您的函数中显示了错误的行?
默认情况下,调试器会尝试向您显示相关信息。由于您的代码通常更有可能存在错误而不是库代码,因此调试器将在调用堆栈上显示您的代码的最新实例。例如,如果在调用 free
的特定实现深度中发生错误,则不太可能是库堆代码出错,因此将识别调用 free
的代码作为可能的罪魁祸首。
在您的情况下,调用堆栈中有 none 代码,因此算法无法找到任何代码,并向您显示了错误的位置。
下面的代码没有做任何有趣的事情,但神秘的是为什么 Dr Memory 会认为存在单元化读取?有什么想法吗?
#include <memory>
int main(int argc, const char* argv[])
{
int aa[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
std::unique_ptr<int[]> p {new int[10]};
for (auto i = 0; i < 10; ++i) {
p[i] = aa[i];
}
return 0;
} // <-- Dr Memory says UNINITIALIZED READ here
编辑:这是完整的错误详细信息。
Error #1: UNINITIALIZED READ: reading 0x0028ff20-0x0028ff24 4 byte(s)
# 0 __mingw_glob [src/main.cpp:14]
# 1 _setargv [src/main.cpp:14]
# 2 __mingw_CRTStartup
# 3 mainCRTStartup
# 4 ntdll.dll!RtlInitializeExceptionChain +0x62 (0x772c8fe2 <ntdll.dll+0x38fe2>)
# 5 ntdll.dll!RtlInitializeExceptionChain +0x35 (0x772c8fb5 <ntdll.dll+0x38fb5>)
Note: @0:00:00.297 in thread 9780
Note: instruction: cmp (%esi) [=11=]x0040a11e
您的 main
函数中指示的行不是发生错误的行。如堆栈跟踪所示,错误发生在 __mingw_glob
中,并且发生在 在 调用任何代码之前。 (这是扩展命令行上传递的文件名通配符的函数。在 Linux 上,这项工作由 shell 完成,但在 Windows 上,它是 C 运行时的责任。)
换句话说,它出现在 mingw
库中。这很可能是无害的误报,您应该简单地添加一个排除项。
我认为 Dr Memory 可能错误地将其识别为未初始化,因为它在您的任何代码 运行 之前由操作系统初始化,或者在 DrMemory 初始化之前由 运行 的代码初始化,或者因为它被传递给了一个系统调用,该系统调用实际上并不读取内存而只写入内存。
为什么它在您的函数中显示了错误的行?
默认情况下,调试器会尝试向您显示相关信息。由于您的代码通常更有可能存在错误而不是库代码,因此调试器将在调用堆栈上显示您的代码的最新实例。例如,如果在调用 free
的特定实现深度中发生错误,则不太可能是库堆代码出错,因此将识别调用 free
的代码作为可能的罪魁祸首。
在您的情况下,调用堆栈中有 none 代码,因此算法无法找到任何代码,并向您显示了错误的位置。