kbhit for Linux的内存泄漏

时间:2019-02-18 05:58:15

标签: c++ memory-leaks windows-subsystem-for-linux termios kbhit

代码为here。当我运行程序时(我将kbhit保存为头文件并保存在程序文件夹中),在使用kbhit的第一个实例上我获得了未初始化的读取访问权限(我正在使用DrMemory进行内存调试)。我加入了sys / ioctl.h,因为没有它,我的程序将无法使用FIONREAD。问题在于调用tcsetattr(STDIN,TCSANOW,&term);。我不完全了解它是如何工作的,因此不胜感激。谢谢!

编辑:确切的消息是“未初始化读取:读取12个字节。系统调用ioctl.0x5402参数#2。”该行来自tcsetattr()调用。 将kbhit保存为cpp文件并将其模板化到另一个文件后,将发生此错误。该程序运行正常,除了一个错误。

1 个答案:

答案 0 :(得分:0)

这是我修改为实际C而不是C ++的代码版本,因为出于粗心,它只是C ++,带有布尔型true / false和struct关键字。

哦,是的,不要将其放在头文件中。将其放在名为kbhit.c的文件中,然后删除或注释掉测试主函数。并在头文件中编写以下行:

int _kbhit(void);

或者您可能需要:

extern "C" int _kbhit(void);

这就是标题中所需的全部内容。

/**
 Linux (POSIX) implementation of _kbhit().
 Morgan McGuire, morgan@cs.brown.edu
 */
#include <stdbool.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>

int _kbhit(void) {
        static bool initialized = false;

        if (! initialized) {
                // Use termios to turn off line buffering
                struct termios term;
                tcgetattr(STDIN_FILENO, &term);
                term.c_lflag &= ~ICANON;
                tcsetattr(STDIN_FILENO, TCSANOW, &term);
                setbuf(stdin, NULL);
                initialized = true;
        }

        int bytesWaiting;
        ioctl(STDIN_FILENO, FIONREAD, &bytesWaiting);
        return bytesWaiting;
}

//////////////////////////////////////////////
//      Simple demo of _kbhit()

int main() {
        printf("Press any key");
        while (! _kbhit()) {
                printf(".");
                fflush(stdout);
                usleep(1000);
        }
        printf("\nDone.\n");

        return 0;
}

在我看来,这是正确的,而valgrind没有抱怨。我没有记忆博士可查。

此代码的工作方式是,它首先使用tcgetattr来读取termios(我认为是终端输入输出设置)结构。然后,通过取消设置ICANON位来对其进行修改。佳能是终端的规范设置,其中包括行缓冲。然后,它将新的termios值写回到终端。与tcsetattr

ioctl调用获取缓冲区中正在等待多少字节。如果有字节在等待,那么有人按下了某些键。