【问题标题】:Imposible declaration INT variable in my program在我的程序中不可能声明 INT 变量
【发布时间】:2015-07-15 21:26:00
【问题描述】:

我尝试用 C++ 创建一个小项目。我的程序应该能够读取 Windows 中当前正在运行的进程,并每 5 分钟将有关进程的信息发送到我的私有 MySQL 数据库。在这段时间内,我可以阅读流程。

见下面的代码:

#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

bool getAllProcesses(void);

int main(void){
    getAllProcesses();
}

bool getAllProcesses(){
    HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    LPPROCESSENTRY32 pe32;

    Process32First(snapshot, pe32);
    while(Process32Next(snapshot, pe32)){
        std::cout << pe32->szExeFile << "\n";
    }
    std::cout << "End of list";
    CloseHandle( snapshot );
    return true;
}

上面的代码运行良好。

但如果我添加代码“int i;i=1;”像这样:

#include <stdio.h>
#include <iostream>
#include <windows.h>
#include <tlhelp32.h>

bool getAllProcesses(void);

int main(void){
    getAllProcesses();
}

bool getAllProcesses(){
    int i;
    i=0;
    HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
    LPPROCESSENTRY32 pe32;

    Process32First(snapshot, pe32);
    while(Process32Next(snapshot, pe32)){
        std::cout << pe32->szExeFile << "\n";
    }
    std::cout << "End of list";
    CloseHandle( snapshot );
    return true;
}

进行此更改后,程序将崩溃,并显示警告“程序停止工作”。

我试图找出问题所在,并确定了以下几点:

如果我使用函数 Process32First() OR Process32Next() 我不能在所有程序中声明相同的 int。

有什么问题?

【问题讨论】:

  • 你用什么平台构建这个?什么操作系统版本?你在 Windbg 中跑过吗?
  • 我使用开源 Code::blocks 13.12(编译器:GNU GCC Compiler)并在 Windows 10 build 10166 上尝试此操作

标签: c++ winapi c++11 int declaration


【解决方案1】:

这里有很多问题。我在 VS 2008 Win7 上试过这个。 “i”声明与问题无关,但可能只是稍微移动堆栈以隐藏真正的问题。在下面更正的代码中查看我的 cmets。

  bool getAllProcesses(){
        int i;
        i=0;
        HANDLE WINAPI snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
       /* replace LPPROCESSENTRY32 with PROCESSENTRY32. LP is just a define as
 a pointer to a structure, so you did not actually allocate any memory for the
 return of Process32First() to return the result into.
 So you were probably overwriting stuff in the stack. */

        PROCESSENTRY32 pe32;

       /* need to initialize the structure properly. Memset may be overkill,
         but better to see all zeros than garbage.  dwSize must be
         initialized as per the SDK documentation. */
        memset(&pe32,0,sizeof(pe32) );
        pe32.dwSize = sizeof(pe32);
        BOOL result;

        /* did not check the result from the call if TRUE/FALSE */
        result = Process32First(snapshot, &pe32);

        std::cout << "result ="  << result << "\n";
        while(Process32Next(snapshot, &pe32)){
            std::cout << pe32.szExeFile << "\n";
        }
        std::cout << "End of list";
        CloseHandle( snapshot );
        return true;
    }

【讨论】:

  • PROCESSENTRY32 pe32 = {sizeof(PROCESSENTRY32)}; 是一种更简洁的初始化方式。
  • 对初学者来说不太直观。
  • 即使作为一个非初学者,我也更喜欢这个答案中显示的代码。这是一种自我记录,而哈利当然不是。
【解决方案2】:

添加这 2 行使程序无法运行只是巧合。程序根本不应该运行,因为有两个主要错误:

  • pe32 是一个未初始化的指针

  • PROCESSENTRY32 结构的

    dwSize 成员未按照[MS.Docs]: Process32First function 中所述进行初始化:

    调用应用程序必须将PROCESSENTRY32dwSize 成员设置为结构的大小(以字节为单位)。

第三个较小的错误是您忽略了 Process32First 返回的流程数据。

为了使事情正常工作,请替换以下代码行:

LPPROCESSENTRY32 pe32;

Process32First(snapshot, pe32);
while(Process32Next(snapshot, pe32)){
    std::cout << pe32->szExeFile << "\n";

,与:

PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);

if (Process32First(snapshot, &pe32))
{
    do {
        std::cout << pe32.szExeFile << "\n";
    }
    while (Process32Next(snapshot, &pe32));
}

【讨论】:

  • 原始代码(和您的代码)中存在第三个错误。 Process32First() 返回的数据将被忽略。代码应使用do/while 循环,以便处理第一组pe32 数据。
  • 没错,我太专注于错误本身,以至于忽略了返回值。
  • 跳过第一组返回数据不是忽略返回值的问题,而是代码逻辑本身的问题。
  • 感谢您改进帖子。那不是我的解决方案,您发现的缺陷从 cmets 中可以看到,我只是说,我觉得我在为您的工作赢得荣誉 :)。
  • 我认为我有足够的声誉,可以节省几点 :) 此外,您发现了导致代码崩溃的真正错误,我只是发现了一个丢失数据的错误。
猜你喜欢
  • 1970-01-01
  • 2021-11-29
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多