【问题标题】:strcat error "Unhandled exception.."strcat 错误“未处理的异常..”
【发布时间】:2013-05-17 08:38:07
【问题描述】:

我的构造函数的目标是:

打开一个文件 读入特定字符串之间存在的所有内容(“%%%%%”) 将每个读取的行放在一个变量(历史)中 将最终变量添加到 char (_stories) 类型的双指针 关闭文件。

但是,当我使用 strcat 时,程序崩溃了。但我不明白为什么,我尝试了好几个小时都没有结果。 :/

这里是构造函数代码:

Texthandler::Texthandler(string fileName, int number) 
        : _fileName(fileName), _number(number)  
{
    char* history = new char[50];

    _stories = new char*[_number + 1]; // rows
    for (int j = 0; j < _number + 1; j++)
    {
        _stories[j] = new char [50]; 
    }
        _readBuf = new char[10000]; 

    ifstream file;
    int controlIndex = 0, whileIndex = 0, charCounter = 0;

    _storieIndex = 0;

    file.open("Historier.txt"); // filename 
    while (file.getline(_readBuf, 10000))
    {
        // The "%%%%%" shouldnt be added to my variables
        if (strcmp(_readBuf, "%%%%%") == 0)
        {
        controlIndex++;
        if (controlIndex < 2)
        {
            continue;
        }
    }

    if (controlIndex == 1)
    {
        // Concatenate every line (_readBuf) to a complete history
        strcat(history, _readBuf);
        whileIndex++;
    }

    if (controlIndex == 2)
    {
        strcpy(_stories[_storieIndex], history);

        _storieIndex++;
        controlIndex = 1;
        whileIndex = 0;
        // Reset history variable
        history = new char[50];

    }
}
file.close(); 
}

我也尝试过没有结果的字符串流..

编辑:忘记发布错误消息: “Step3_1.exe 中 0x6b6dd2e9 (msvcr100d.dll) 处的未处理异常:0xC00000005:访问冲突写入位置 0c20202d20。” 然后打开一个名为“strcat.asm”的文件..

最好的问候 罗伯特

【问题讨论】:

    标签: c++ visual-c++


    【解决方案1】:

    您在堆栈的某处发生了缓冲区溢出,这一点可以从您的指针之一是0c20202d20(几个空格和一个- 符号)这一事实得到证明。

    可能是因为:

    char* history = new char[50];
    

    对于您要放入的内容来说不够大(或者它没有正确设置为 C 字符串,以 \0 字符结尾)。

    我不完全确定为什么您认为每个高达 10K 的多个缓冲区可以连接成一个 50 字节的字符串:-)

    【讨论】:

      【解决方案2】:

      strcat 在以 null 结尾的 char 数组上运行。在行中

      strcat(history, _readBuf);
      

      history 未初始化,因此不能保证有一个空终止符。您的程序可能会读取分配的内存之外的内存以寻找'\0' 字节,并在此时尝试复制_readBuf。超出为history 分配的内存写入会调用未定义的行为,并且很有可能发生崩溃。

      即使您添加了空终止符,history 缓冲区也比 _readBuf 短得多。这使得内存很可能被覆盖 - 您需要使 history 至少与 _readBuf 一样大。

      或者,既然这是 C++,为什么不使用 std::string 而不是 C 风格的 char 数组?

      【讨论】:

      • 谢谢你们!通过您的回答,我解决了问题! :)
      • 很高兴能帮上忙。由于您是新用户,我希望您不介意我在accepting answers上指出一些注释
      猜你喜欢
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-26
      • 2016-04-11
      • 2017-10-31
      • 1970-01-01
      相关资源
      最近更新 更多