调试器有正确的输出,但正常执行没有

Debugger has correct output but normal execution does not

我遇到了一个奇怪的问题,当我通过调试器 运行 时,我的代码完全符合我的要求,但当我 运行 它正常时,它却不起作用。奇怪的是我也没有收到 运行time 错误。这可能是问题所在,但我对此不是 100% 确定:

void calcMostMissed (double *ptr, int totalContestants, int arrSize)
{
    //output header
    cout << endl << "MOST MISSED QUESTIONS" << endl;

    //check how many times a question is missed and its percentage, then output it if it's above 60%
    double curQuest = *ptr;
    int freq = 0;
    int j = 0;
    double percentMissed;
    for (int i = 0; i <= arrSize; i++)     //loop through the missed questions array
    {
        if (*(ptr + i) > 0)      //if pointer is pointing at a question number (extra space in array is set to 0)...
        {
            if (*(ptr + i) == curQuest)      //then check how often it occurs in the array
            freq++;
        }
        else    //if the pointer is not pointing at a question number anymore...
        {
            //calculate percent missed and output it if its 60% or greater
            percentMissed = (static_cast<double>(freq) / totalContestants) * 100;
            if (percentMissed >= 60)
            {
                cout << static_cast<int>(curQuest) << "\t" << fixed << setprecision(2) << percentMissed << "%" << endl;
            }
            // check if the question's percentage missed has already been calculated and evaluated
            j++;
            curQuest = *(ptr + j);
            int r = 0;
            while (r < j)
            {
                if (*(ptr + r) == curQuest)
                {
                    if (j < arrSize - 1)
                    {
                        j++;
                        curQuest = *(ptr + j);
                    }
                }
                r++;
            }
            if (!(j == arrSize - 1 && r == arrSize - 1))
            {
                i = 0;
            }
            freq = 0;
        }
        //if the current question variable has been through all missed question, then leave loop
        if (curQuest < 1)
        {
            break;
        }
    }
}

此函数总体上应该做的是找到所有遗漏问题的遗漏百分比,并仅输出超过 60% 的问题。

这是我的调试器输出的内容(以及我希望它看起来的样子):

Enter name of answer key file: batch7a.txt
Enter name of contestant's answers file: allWrongContestants.txt
oo12345678 - 0.00
1 2 3
C A B
A B C

0012387654 - 0.00
1 2 3
C A B
A B C

0012364213 - 0.00
1 2 3
C A B
A B C

Mean: 0.00
Median: 0.00
Mode: 0.00

MOST MISSED QUESTIONS
1       100.00%
2       100.00%
3       100.00%

这是正常执行的输出:

Enter name of answer key file: batch7a.txt
Enter name of contestant's answers file: allWrongContestants.txt
oo12345678 - 0.00
1 2 3
C A B
A B C

0012387654 - 0.00
1 2 3
C A B
A B C

0012364213 - 0.00
1 2 3
C A B
A B C

Mean: 0.00
Median: 0.00
Mode: 0.00

MOST MISSED QUESTIONS

Process returned 0 (0x0)   execution time : 14.442 s
Press any key to continue.

我的调试器运行一直到我的程序结束都很好,但由于某种原因,正常执行仍然存在缺陷。欢迎提出任何建议,我会澄清我可能忘记提及的任何内容。

如果有帮助,我正在使用 Code::Blocks 作为我的 IDE

关于我的代码的一些其他信息:有 3 个问题,所有参赛者在测试中的得分为 0%,这意味着所有问题的答案都不正确。

输出:数字是参赛者的ID,旁边是他们的分数,下面的数字列表是他们做错的题号,下面是参赛者的答案,下面是正确答案。

这是调用calcMostMissed函数的函数:

void statReport (double *ptr, int totalScores, double *mmqPtr, int arrSize)
{
    //calculate mean of scores
    double mean = calcMean(ptr, totalScores);

    //calculate median of scores
    double median = calcMedian(ptr, totalScores);

    //calculate mode of scores
    double *mode = calcMode(ptr, totalScores);

    //output to console the data
    cout << "Mean: " << fixed << setprecision(2) << mean << endl;
    cout << "Median: " << median << endl;
    cout << "Mode: ";
    sort(mode, mode + totalScores);
    int j = 0;
    for (int i = 0; i < totalScores; i++)
    {
        if (*(mode + i) != -1)
        {
            if (j == 0)
            {
                cout << *(mode + i);
            }
            else
            {
                cout << ", " << *(mode + i);
            }
            j++;
        }
    }
    cout << endl;

    //call calcMissedQuestions function
    calcMostMissed(mmqPtr, totalScores, arrSize);

    //delete pointers
    delete[] mode;
    mode = nullptr;
    delete[] mmqPtr;
    mmqPtr = nullptr;
}

这是主要功能:

int main()
{
    string answerKeyName;
    string contestantAnswerName;
    ifstream answerKeyFile;
    ifstream contestantAnswerFile;

    //ask for file names
    cout << "Enter name of answer key file: ";
    cin >> answerKeyName;
    cout << "Enter name of contestant's answers file: ";
    cin >> contestantAnswerName;

    //check if files can be opened properly
    answerKeyFile.open(answerKeyName, ios::binary);
    contestantAnswerFile.open(contestantAnswerName, ios::binary);
    if(!answerKeyFile)
    {
        cout << "Answer key file could not be opened" << endl;
        exit(EXIT_FAILURE);
    }
    if (!contestantAnswerFile)
    {
        cout << "Contestant's answers file could not be opened" << endl;
        exit(EXIT_FAILURE);
    }

    //find how many contestant's there are
    int i = 0;
    string temp;
    while (contestantAnswerFile.good())
    {
        getline(contestantAnswerFile, temp);
        if (temp != "")
        {
            i++;
        }
    }
    contestantAnswerFile.clear();
    contestantAnswerFile.seekg(0, ios::beg);

    //create contestant's score array
    double *scorePtr = new double[i];

    //create pointer for all missed questions
    double *mmqPtr = nullptr;
    int arrSize;

    //compare the contestant's answers to the answer key, then fill array with score
    double score;
    for (int c = 0; c < i; c++)
    {
        score = compareAnswers (contestantAnswerFile, answerKeyFile, mmqPtr, i, arrSize);
        *(scorePtr + c) = score;
    }

    //create the statistics report
    statReport(scorePtr, i, mmqPtr, arrSize);

    //delete dynamically allocated array
    delete[] scorePtr;
    scorePtr = nullptr;

    //close files
    answerKeyFile.close();
    contestantAnswerFile.close();

    return 0;
}

下面是我认为的问题所在,但是我仍然无法正确编译它,因为没有提供其他函数和输入文件,可能是正确的,以免进一步堵塞问题:

double *mmqPtr = nullptr;main() 中定义,然后它被传递给statReport() 函数而没有与任何对象相关联。 之后它作为函数 calcMostMissed() 的第一个参数并在其中被取消引用,但仍然是 nullptr,因此这会产生未定义的行为。

正如评论中指出的那样,循环内也存在索引越界的问题。