gpt4 book ai didi

c++ - 段错误和神秘的循环行为

转载 作者:太空宇宙 更新时间:2023-11-04 14:17:24 24 4
gpt4 key购买 nike

我正在完成一项有一些特定要求的家庭作业。必须有一个名为 TestScores 的类,该类将分数数组作为其参数。如果任何分数为负或大于 100,它会抛出异常。最后,它必须有一个返回所有分数的平均值的成员函数。我不够聪明,找不到一种方法只将数组传递给构造函数,所以我还添加了一个 int 来指示数组的大小。

运行代码(我什至还没有开始测试异常),我不断收到段错误。 Valgrind 和 gdb 一直没有帮助,输出如下消息:

==9765== Jump to the invalid address stated on the next line
==9765== at 0x2200000017: ???

更神秘的是(至少对我而言),在客户端代码的 for 循环中,我的增量器 i 在创建 TestScores 对象后不知何故从 0 突然变成一个看似随机的两位数。在以前的版本中,在我开始使用 rand() 填充数组之前,我只是从不递增并执行无限循环。

这是 TestScores.cpp 的内容:

#include <iostream>
using std::cout;
using std::endl;
#include "TestScores.h"
#include <stdexcept>
using std::runtime_error;

// Constructor.
TestScores::TestScores(int a[], int s):
_SIZE(s), _scores()
{
// Look at each item in a[], see if any of them are invalid numbers, and
// only if the number is ok do we populate _scores[] with the value.
for (int i = 0; i < _SIZE; ++i)
{
if (a[i] < 0)
{
throw runtime_error ("Negative Score");
}
else if (a[i] > 100)
{
throw runtime_error ("Excessive Score");
}
_scores[i] = a[i];
cout << _scores[i] << " ";
}
cout << endl;
}

// Finds the arithmetic mean of all the scores, using _size as the number of
// scores.
double TestScores::mean()
{
double total = 0;
for (int i = 0; i < _SIZE; ++i)
{
total += _scores[i];
}
return total / _SIZE;
}

// median() creates an array that orderes the test scores by value and then
// locates the middle value.
double TestScores::median()
{
// Copy the array so we can sort it while preserving the original.
int a[_SIZE];
for (int i = 0; i < _SIZE; ++i)
{
a[i] = _scores[i];
}

// Sort the array using selection sort.
for (int i = 0; i < _SIZE; ++i)
{
int min = a[i];

for (int j = i + 1; j < _SIZE; ++j)
{
if (a[j] < min)
{
min = a[j];
a[j] = a[i];
a[i] = min;
}
}
}

// Now that array is ordered, just pick one of the middle values.
return a[_SIZE / 2];
}

这是客户端代码:

#include <iostream>
#include "TestScores.h"
#include <stdexcept>
#include <cstdlib>
#include <ctime>
using std::exception;
using std::cout;
using std::endl;

int main()
{
const int NUM_STUDENTS = 20,
NUM_TESTS = 4;
int test [NUM_TESTS][NUM_STUDENTS];

// Make random seed to populate the arrays with data.
unsigned seed = time(0);
srand(seed);

// Populate the scores for the individual tests graded for the semester.
// These will all be values between 0 and 100.
for (int i = 0; i < NUM_TESTS; ++i)
{
for (int j = 0; j < NUM_STUDENTS; ++j)
{
test[i][j] = rand() % 100;
cout << test[i][j] << " ";
}
cout << endl;
}

// Now we have the data, find the mean and median results for each test.
// All values should be valid, but we'll handle exceptions here.
for (int i = 0; i < NUM_TESTS; ++i)
{
cout << "For Test #" << i + 1 << endl;
try
{
cout << "i = " << i << endl; // i = 0 here.
TestScores results(test[i], NUM_STUDENTS);
cout << "i = " << i << endl; // i = some random number here.
cout << "Mean: " << results.mean() << endl;
cout << "Median:" << results.median() << endl << endl;
}
catch (exception &e)
{
cout << "Error, invalid score: " << e.what() << endl;
}
cout << "For Test #" << i + 1 << endl;
}

return 0;
}

编辑:还请求 header :

#ifndef TEST_SCORES_H
#define TEST_SCORES_H

class TestScores
{
private:
const int _SIZE;
int _scores[];

public:
// Constructor
TestScores(int a[], int);

double mean() const,
median() const;
};
#endif

我试着让数组动态化,并且没有将数组初始化为空,这解决了我的问题,所以这就是我最终提交的内容。这让我想到了一些后续问题。

在进入动态之前,我通过尝试为它提供应该已经初始化的大小值来尝试初始化数组 _scores。这导致了编译器问题。我和我的老师谈过这个,他说你不能为数组分配空间,除非有一个硬连线的全局常量。也就是说,您不能在构造函数中传递大小值来初始化数组。这是真的吗?如果是,为什么?

退后一步,在我看来,如果您需要很多值,动态数组会更好,因为这样您就不需要内存中的连续空间 block 。因此,如果您正在制作小型数组,那么制作动态数组似乎是在浪费空间和时间。这是不真实的吗?从现在开始,我是否应该将所有阵列都作为动态阵列?这段经历肯定改变了我对常规数组实用性的看法,至少在它们与类相关时是这样。

此外,尽管我在作业中获得了满分,但我觉得我通过传递大小参数违反了精神(因为文字问题陈述如下:“类构造函数应该接受一组测试分数作为其参数” ).除了硬连线的全局常量或具有大小参数之外,有没有办法只传递数组?我发誓我花了一个小时想办法做到这一点。

最佳答案

您似乎根本没有初始化 _scores。您需要在构造函数的顶部使用 _scores = new int[s];(在析构函数中还需要 delete[] s;)。

如果不初始化 _scores,您会将内容写入未定义的内存位置。

关于c++ - 段错误和神秘的循环行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10127535/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com