0

我的构造函数的目标是:

打开文件读入特定字符串(“%%%%%”)之间存在的所有内容 将每个读取的行放在一个变量(历史)中 将最终变量添加到 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(); 
}

我也尝试过使用 stringstream 没有结果..

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

最好的问候罗伯特

4

2 回答 2

2

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

大概是因为:

char* history = new char[50];

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

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

于 2013-05-17T08:42:04.240 回答
1

strcat对空终止char数组进行操作。在行

strcat(history, _readBuf);

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

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

或者,既然这是 C++,为什么不使用std::stringC 风格的char数组来代替呢?

于 2013-05-17T08:42:13.813 回答