是我的编译器将适当的代码优化为无用的崩溃代码
Is my compiler optimizing away proper code into useless crashing code?
我正在尝试编写一个函数,在多个消息框中显示系统中所有线程所属进程的PID。
void CheckProcess()
{
LPCSTR blahzix;
HANDLE tsnap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD, 0);
THREADENTRY32 tentry;
tentry.dwSize = sizeof (tentry);
BOOL CRec = Thread32First(tsnap, &tentry);
GetLastError();
while (CRec)
{
blahzix = tentry.th32OwnerProcessID;
MessageBox (NULL, NULL, blahzix, MB_OK);
CRec = Thread32Next(tsnap, &tentry);
}
CloseHandle(tsnap);
}
我对为什么这不能工作一段时间感到困惑,所以我在OllyDBG中打开它,发现MessageBox
的代码有第三个参数直接接收PID数据,而不是接收一个地址,其中PID存储为字符串,导致MessageBox
函数试图访问存储在00000004的数据时访问违规。如果我删除行blahzix = tentry.th32OwnerProcessID;
并附加第三行,看起来像这样:LPCSTR blahzix = "anything";
然后,而不是崩溃MessageBox
正确显示一个标题为anything的消息框。
为什么会发生这种情况?我认为编译器决定"变量blahzix不用于任何地方,除了在这个消息框函数,它总是等于tentry。"th32OwnerProcessID所以它们可能是相同的变量,我将去掉它并让messagebox使用那个变量。"
编辑:让我重新表述一下我的问题。如果LPCSTR blahzix = "fdisaf";
使用=运算符,并且=运算符应该将左侧变量的值更改为右侧数据或变量的值,那么它如何用于为blahzix创建字符串是有效的?由于blahzix显然实际上是一个指针,我认为=操作符应该只改变变量指向的位置,而不是改变其中的内容。怎么来使用=操作符在这个实例中改变它指向的字符串的数据,并在这个实例中使用它:blahzix = tentry.th32OwnerProcessID;
改变指针的数据,而不是字符串的数据?=操作符不应该改变其中一个吗?如何使=运算符指定要更改的数据? THREADENTRY32::th32OwnerProcessID
是DWORD
,而不是字符串。将其赋值给指针并将其作为字符串处理是没有意义的。它也是无效的(没有显式强制转换的约束违反);
不要把自己的错误归咎于编译器。编译器bug是非常非常罕见的。
blahzix = tentry.th32OwnerProcessID;
不会将整型进程id转换为字符串。它只是将进程id作为blahzix
指向的地址写入。你不拥有这个地址的内存,所以试图从它显示一个字符串会导致未定义的行为。可能会发生车祸。
要通过MessageBox
将进程id显示为字符串,需要将其转换为char
数组。在c++ 11的支持下,你可以通过修改
blahzix = tentry.th32OwnerProcessID;
MessageBox (NULL, NULL, blahzix, MB_OK);
std::string s = std::to_string(tentry.th32OwnerProcessID);
char const *pchar = s.c_str();
MessageBox (NULL, NULL, pchar, MB_OK);
或者,如果您仅限于使用C(问题标记为c++,但代码都是C),您可以使用
char str[12];
sprintf(str, "%d", tentry.th32OwnerProcessID);
MessageBox (NULL, NULL, str, MB_OK);
- 为什么代码会崩溃?(在CPP中)
- 为什么此代码会崩溃?(我是C 的新手)
- C和C 中的代码优化
- 使用清理代码优化多个出口点
- 在 c++ 中从 txt 文件中提取条目的代码优化问题
- 返回向量<对<字符串,字符串>>会导致 gcc 编译代码 (curlcpp) 崩溃
- 为什么传递值参数经常使编译器更容易进行代码优化
- 来自MATLAB的代码优化直方图C
- C - 代码优化
- 代码优化子集总和
- 在代码优化过程中,C++11编译器是否会在可能的情况下将局部变量转换为右值
- C++-筛选Atkin代码优化
- 协议缓冲区 GetRepeatedField (反射) 代码优化
- 应用程序在执行以下代码时崩溃
- 为什么这个C++代码会崩溃
- 使用emcc-O2编译基本代码时崩溃
- C++代码优化
- 编译和代码优化
- C++ ARM 设备上代码优化的提示
- 是我的编译器将适当的代码优化为无用的崩溃代码