【问题标题】:Access violation error - ucrtbased.dll访问冲突错误 - ucrtbased.dll
【发布时间】:2018-09-27 16:49:08
【问题描述】:

在 ChatClient.exe 中的 0x0F4CD6F0 (ucrtbased.dll) 处引发异常:0xC0000005:访问冲突读取位置 0x00000068。

几天来我一直在努力寻找这个错误的根源,我终于隔离了一个 sn-p 来说明我遇到的问题。在 switch 语句之后立即抛出异常。我不知道是什么导致了这段相对平凡的代码中的“访问冲突”,您可以在下面看到:

#include <iostream>
#include <string>
#include <conio.h>

int main(){
    bool room = true, type = true;
    string input;
    unsigned int scroll = 0;
    while (room) {
        cout << input;
        /* Input */
        int ch = _getch();
        switch (ch) {
        case 72: /* scroll up */
            if (!type && scroll != sizeof(unsigned int))
                scroll++;
            break;
        case 80: /* scroll down */
            if (!type && scroll != 0)
                scroll--;
            break;
        case 13: /* Send message */
            input.clear();
            scroll = 0;
            break;
        case 27: // Quit loop
            room = false;
            break;
        case 9: // Switch between scrolling and typing modes
            if (type)
                type = false;
            else
                type = true;
            break;
        default:
            if (type && ch != -32) {
                input.append((char*)ch);
            }
            break;
        }
    } <- Exception thrown, probably when the while loop condition is re-evaluated?
    return 0;
}

将 Visual Studio 2017 与默认 IDE 调试工具结合使用。

【问题讨论】:

  • “我这几天一直在努力寻找这个错误的根源” 是否有任何困难包括使用调试器? input.append((char*)ch); ...什么?为什么要转换为指针?然后string 将尝试读取该内存地址...您想要的是在相应的内存地址处附加一个ASCII char,而不是char*。因此,我投票决定关闭它,因为它是由一个简单的印刷错误引起的。
  • 请避免使用magic numbers。如果通过例如13 你的意思是 ASCII 回车字符 '\r' 然后 say 所以使用实际字符。
  • 我使用了“幻数”,因为 _getch 返回类型为 int。以后我会更加小心的。
  • input.append((char*)ch); 是个坏主意 ;)
  • 没关系。使用 ASCII 然后 '\r' == 13.

标签: c++ access-violation


【解决方案1】:
input.append((char*)ch);

为什么要转换为指针?这是非常错误的。由于函数重载解析,std::string 将尝试从与该字符的强制转换 ASCII 值对应的内存地址开始读取 C 字符串……这不是您要使用的内存。因此,访问冲突......充其量是。

您想要的是在相应的内存地址处附加一个 ASCII char,而不是一个 char*

当您使用它时,请使用正确的 C++ 类型转换,这会在这个问题上出错,并且永远不会让您编译它。再说一次,如果你有任何警告,即使是旧的 C 演员也应该至少警告过这一点。

input.append( static_cast<char>(ch) );

(注意:我假设 getch() 不会返回任何 int 在您的情况下无法安全地转换为 char。我没有查看它的文档,因为它似乎是一些旧的 conio愚蠢。如果该值可能超出范围,则您有责任进行检查,因为在导致溢出时进行强制转换最多会调用 undefined unreliable/non-portable 行为。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多