【问题标题】:Unhandled Exceptions in simple application简单应用程序中未处理的异常
【发布时间】:2014-05-25 23:50:42
【问题描述】:

我对 C++ 和一般编码相当陌生,我正在使用 Visual Studio 2013 Desktop 编写一个简单的程序来收集 .CSV 文件中的数据并对其执行一些操作。该程序似乎编译和运行良好,并要求我输入要打开的文件的名称。就像我想的那样,如果我输入一个无效的文件名,程序将显示一条错误消息并终止,但是如果我输入正确的名称,我会收到一条消息,上面写着

“TestIO.exe 中 0x0F16A9E8 (msvcr120d.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0xCCCCCCC0。”

带有中断或继续选项。如果我按继续,它会再次显示相同的消息,并无限继续,直到我按“中断”并停止调试。我完全不知道这里发生了什么,有人可以对此有所了解吗?将不胜感激。

编辑:这是我的 main()。希望这对您有所帮助,抱歉之前没有包含它。

int main()
{
    int numDays = 0, streams;
    string* date;
    string line, filename;
    DailyData* days;
    cout << "Enter file name: ";
    getline(cin, filename);
    ifstream infile;
    infile.open(filename); 
    if (infile.fail())
    {
        cout << "Error opening input file" << endl;
        return 0;
    }
    while (getline(infile, line))
        numDays++;
    date = new string[numDays];
    for (int i = 0; i < numDays; i++)
        getline(infile, date[i]);
    days = new DailyData[numDays];
    for (int i = 0; i < numDays; i++)
    {
        getData(date[i], streams);
        days[i] = DailyData(date[i], streams);
    }
    cout << "Max Streams: " << maxStreams(days, numDays) << endl;
    cout << "Min Streams: " << minStreams(days, numDays) << endl;
    cout << "Avg Streams: " << average(days, numDays) << endl;
    cout << "Tot Streams: " << total(days, numDays) << endl;
    delete[] days;
    delete[] date;
    infile.close();
    return 0;
}

编辑 2:这是你们要求的一些东西

void getData(string& d, int& s)
{
    int start = 0, end = 0, i = 0;
    string p[14];
    while (start != string::npos)
    {
        end = d.find(",", start); 
        p[i] = d.substr(start, end - start);
        start = end + 1;
        i++;
    }
    d = p[0];
    s = atoi(p[5].c_str());
}

这里是 DailyData 及其构造函数

class DailyData
{
    public:
    DailyData() :date("NULL"), streams(0){}
    DailyData(string d, int s) :date(d), streams(s){}
    string getDate(){ return date; }
    int getStreams(){ return streams; }
    friend ostream& operator << (ostream&, DailyData&);
    private:
        string date;
        int streams;
};

编辑 3:我将代码更改为使用向量而不是数组。除了更改 int main() 之外,我还确保更改所有函数定义/声明中的参数。我仍然收到与我最初遇到的相同的未处理异常错误。这是新的代码 sn-p:

vector<string> date;
vector<DailyData> days;

//...

while (getline(infile, line))
{
    date.push_back(line);
    getData(date.back(), streams);
    days.push_back(DailyData(date.back(), streams));
}
numDays = days.size();

【问题讨论】:

  • 您最好在问题中包含一些相关代码...
  • 如果没有 sn-p,我们只能猜测您的代码失败的地方,但通常会在您从未初始化的内存中读取时发生访问冲突。
  • 我应该在这篇文章中包含代码的哪一部分?另外,如果代码失败,为什么要编译?
  • 它编译是因为这是一个运行时错误,即静态分析无法确定的东西(例如尝试通过运行时确定的值索引超出数组末尾的索引)。
  • 我看不出有什么特别让我觉得不对劲的地方(虽然你使用 new 和数组是不好的做法,你应该使用 vector),所以它可能会有所帮助放置一些打印语句,以便您可以缩小确切失败的行。按照惯例,您还应该在应用程序以错误状态退出时返回一个不为零的值。

标签: c++ runtime unhandled-exception first-chance-exception


【解决方案1】:

您的代码似乎在您已读到文件末尾后正在对输入文件调用 getline

while (getline(infile, line))
    numDays++;

// above reads every line in the file,
// then you call this, even though while(getline) has returned false:

for (int i = 0; i < numDays; i++)
    getline(infile, date[i]);

如果您是编程新手,请始终使用花括号来显示循环体,以便查看循环块执行的开始和结束位置。

此外,在实践中,最好学习使用调试器。这将是你作为程序员做过的最有价值的事情。

编辑:

以下是如何使用可动态调整大小的向量而不是固定大小的数组:

std::vector<string> dates;

//...

while( getline(infile, line) )
{
    dates.push_back(line);
}

如果您需要更多信息,请搜索 C++ 向量。

编辑2:

现在 getData 的代码已经发布,我认为问题出在那儿。首先,这段代码:

while (start != string::npos)
{
    end = d.find(",", start); 
    p[i] = d.substr(start, end - start);
    start = end + 1;
    i++;
}

看起来很危险。

p[i] = d.substr(start, end - start); 

如果 end == string::npos 会导致奇怪的行为,只要 d.find 找不到逗号就会发生。

同样,如果 end == string::npos

,start = end + 1 不会按照你的预期做

进一步的 p[i] = ... 仅适用于 i 小于 13 的值。我认为没有任何检查可以保证这一点。

我的第一个建议是检查是否 end == string::npos,如果不是,则仅执行其他操作。

希望对您有所帮助,此代码的行为很大程度上取决于您的输入数据的外观,这就是为什么最好使用调试器。

【讨论】:

  • 解决此问题的最佳方法是什么?我应该将 while 循环放在一个单独的函数中,该函数返回行数吗?
  • @ChilledGrease 有什么理由需要先验地知道行数吗?当您遍历文件时,您不能完成所有处理吗?当然,假设您将容器切换到 vectors 而不是裸露的 arrays
  • 我以前从未使用过向量,我会看看如何做到这一点。感谢您的帮助!
  • 好吧,最好的方法可能是使用动态可调整大小的数据结构,例如向量而不是数组。最简单的做法是使用 infile.clear() 将文件指针重置回文件的开头;和 infile.seekg(0, std::ios::beg);
  • 我已经编辑了我的答案,为您提供了一个最小的矢量示例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2016-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-02
相关资源
最近更新 更多