分段错误GetConsoleScreenBufferInfo(WinApi)C ++

时间:2014-07-16 17:54:33

标签: c++ windows winapi segmentation-fault

我在C ++中使用WinApi来更改控制台属性,并在最后两个函数中调用GetConsoleScreenBufferInfo()时出现分段错误错误。

奇怪的是,如果我重现相同的代码 - 只需在main()中使用HANDLE和PCONSOLE_SCREEN_BUFFER_INFO-的相同声明调用GetConsoleScreenBufferInfo(),我得到没有错误,但是如果我在getPosCursorX()内部这样做我仍然得到错误。

命名空间consola {

HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
PCONSOLE_SCREEN_BUFFER_INFO infoCon;

struct TamanoConsola
{
    COORD buffer;
    SMALL_RECT ventana;
} inicial;

void gotoxy(int x, int y)
{
    COORD dwPos;
    dwPos.X=x;
    dwPos.Y=y;

    SetConsoleCursorPosition(hCon, dwPos);
}

void setColor(int texto, int fondo)
{
    SetConsoleTextAttribute(hCon, fondo*16+texto);
}

void setBufferTamano(int ancho, int alto)
{
    COORD buffertamano = {ancho, alto};

    if(SetConsoleScreenBufferSize(hCon, buffertamano) == 0)
        std::cout << "ERROR de WinApi numero: " << GetLastError() << std::endl;
}

void setVentanaTamano(int ancho, int alto)
{
    SMALL_RECT ventanatamano1 ={0, 0, ancho-1, alto-1};
    SMALL_RECT* ventanatamano = &ventanatamano1;

    if(SetConsoleWindowInfo(hCon, TRUE, ventanatamano) == 0)
        std::cout << "ERROR de WinApi numero: " << GetLastError() << std::endl;
}

void setVentanaBufferTamano(int anchoVentana, int altoVentana, int anchoBuffer, int altoBuffer)
{
    setBufferTamano(anchoBuffer, altoBuffer);
    setVentanaTamano(anchoVentana, altoVentana);
}

int getPosCursorX()
{
    GetConsoleScreenBufferInfo(hCon, infoCon);

    return infoCon->dwCursorPosition.X;
}

int getPosCursorY()
{
    GetConsoleScreenBufferInfo(hCon, infoCon);

    return infoCon->dwCursorPosition.Y;
}

}

提前致谢!

1 个答案:

答案 0 :(得分:5)

要解决此问题,不要将infoCon声明为指向CONSOLE_SCREEN_BUFFER_INFO的指针(前缀P表示它是指针),而是将其声明为实际结构:

CONSOLE_SCREEN_BUFFER_INFO infoCon;

然后在需要指向它的指针时使用地址运算符&

GetConsoleScreenBufferInfo(hCon, &infoCon);

为了解释更多,当您声明全局变量时,它们会被编译器运行时系统自动初始化为零。并且指针为零与NULL指针相同。取消引用NULL指针会导致undefined behavior,这在很多情况下会导致崩溃。

了解未定义行为的一个重要事项是,有时它似乎可以工作。有时它似乎完美无缺,有时似乎工作但产生了意想不到的结果,但就像我之前所说的那样,大多数时候程序都崩溃了。

关于变量的初始化。本地(非静态)变量根本没有初始化。使用未初始化的局部变量也是未定义的行为,未初始化的本地变量的值是 indeterminate 。如果你检查它,它似乎是随机的。实际上,由于所有C编译器都将局部变量放在堆栈上,因此该值将是变量位置的内存值。未初始化的局部静态变量与全局变量一样,初始化为零。