使用stringsteam在内存中超出范围的问题

Trouble with Out of range in memory using stringsteam

本文关键字:范围 问题 中超 stringsteam 内存 使用      更新时间:2023-10-16

我刚开始第一次使用stringstream,我喜欢这个概念,但是我很难找到我的stringstream函数在内存中超出范围的地方。

我的函数所做的是接受一个字符串,例如,"N02550 G3 X16.7379 Y51.7040 R0.0115"这是我工作中CNC机器的机器码。我把这个字符串传递给一个stringstream为了找到在它们旁边有X Z Y的字符串,这些是坐标。然后,为了将浮点数保存到我的结构体"坐标"(有3个双精度,x, y, z),它在开头去掉了这个字符。

当我运行一个包含33行机器代码的文本文件时,我的程序工作了。当我用718行的机器码运行它时,它到达718行,然后由于内存超出范围而崩溃。另一个奇怪的地方是,当我运行有118,000行代码的机器码时,它会上升到22,000行,然后崩溃。所以我很难弄清楚为什么它能做到这一点,是什么导致了这个问题。

函数如下:

   void getC(string& line, Coordinates& c)//coordinates holds 3 doubles, x, y, z
{
    //variables
    string holder;
    stringstream ss(line);
    while(ss)
    {
        ss >> holder;
        if(holder.at(0) == 'X')
        {
            holder.erase(0,1);//get rid the the character at the beggining
            stringstream sss(holder);
            sss >> c.x;
            sss.clear();
        }
        if(holder.at(0) == 'Y')
        {
            holder.erase(0,1);
            stringstream sss(holder);
            sss >> c.y;
            sss.clear();
        }
        if(holder.at(0) == 'Z')
        {
            holder.erase(0,1);
            stringstream sss(holder);
            sss >> c.z;
            sss.clear();
        }
        if(ss.eof()) // to get out of the ss stream
            break;
    }
    ss.clear();
}

如果您想查看整个应用程序(应用程序有良好的文档),然后询问是否需要包含机器代码的文本文件。谢谢你!

尝试更改:

while(ss)
{
    ss >> holder;
    ...
    if(ss.eof()) // to get out of the ss stream
        break;
}

简单地说:

while(ss >> holder)
{
    ...
}

并且您可以在每个分支(X/Y/Z)中摆脱对clear的调用,因为它实际上没有做任何事情,因为sss是临时的,并且您没有使用它做任何事情(没有点设置标记在您要丢弃的东西上)。我怀疑你的范围问题是来自ss >> holder失败后试图访问holder.at(0)

您通常希望在读取令牌后立即检查输入失败,同时尝试输入和检查失败的一种方便方法是简单地检查ss >> token是否计算为true。所以我们可以这样写代码:

if (ss >> token)
{
    ...
}
else
{
    // handle failure if necessary
}

我通常发现用这种方法编写代码要比手动检查错误标志容易得多。

作为简化版本:

void getC(string& line, Coordinates& c)
{
    stringstream ss(line);   
    for (string holder; ss >> holder; )
    {
        const char ch = holder.at(0);
        stringstream sss(holder.substr(1));
        if (ch == 'X')
            sss >> c.x;
        else if (ch == 'Y')
            sss >> c.y;
        else if (ch == 'Z')
            sss >> c.z;
    }
}