【问题标题】:Segmentation fault GetConsoleScreenBufferInfo (WinApi) C++分段错误 GetConsoleScreenBufferInfo (WinApi) C++
【发布时间】:2014-07-16 17:54:32
【问题描述】:

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

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

命名空间控制台{

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;
}

}

提前致谢!

【问题讨论】:

  • 你已经统一了指针 infoCon。
  • 你没有为指针infoCon分配内存。
  • @user2120666 未初始化,空指针(全局变量初始化为零)。
  • @JoachimPileborg:是的。谢谢指正。
  • 你也完全忽略了错误检查和滥用全局变量。

标签: c++ windows winapi segmentation-fault


【解决方案1】:

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

CONSOLE_SCREEN_BUFFER_INFO infoCon;

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

GetConsoleScreenBufferInfo(hCon, &infoCon);

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

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

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

【讨论】:

  • 更多关于你正确答案的信息在这里:stackoverflow.com/questions/24472174/…
  • @Joachim Pileborg 我明白了!顺便说一句,愚蠢的错误......让我烦恼的是它在主样本中运行良好,当我在命名空间中更改它时,主样本开始崩溃。这是为什么呢?
猜你喜欢
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-08-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多