Странное и неправильное поведение размера массива в C ++ при инициализации в классе

Я пытаюсь создать класс с именем Player, который имеет массив с именем Score, объявленный с размером в свойствах класса Player. Тем не менее, когда я инициализирую нового игрока, метод sizeof (scores) дает мне 20 и, фактически, инициализирует массив показателей размера 20, а не 5. Мне интересно, почему и как это исправить. Вот код и вывод.

    #include <iostream>
#include <iomanip>
#include <sstream>

using namespace std;

struct stats {
unsigned int min;
unsigned int max;
unsigned int mode;
unsigned int modeFreq;
unsigned int mean;
unsigned int total;
};

class Player {
public:
int scores[5];
stats pStats;
void inputScores();
void calculateStats();
void printScores();
};

void Player::printScores(){
cout << "Printing Scores..." << endl;
for (int i = 0; i < sizeof(scores); i++) {
cout << scores[i] << endl;
}
}

void Player::inputScores(){
for (int i = 0; i < sizeof(scores); i++) {
cout << "Enter a score for [" << i << "]: ";
int input;
cin >> input;
scores[i] = input;
}
}

int main() {
Player p;
cout << sizeof(p.scores);
p.inputScores();
p.printScores();
}

Что дает мне это:

    20
Enter a score for [0]: 1
Enter a score for [1]: 2
Enter a score for [2]: 3
Enter a score for [3]: 4
Enter a score for [4]: 5
Enter a score for [5]: 6
Enter a score for [6]: 7
Enter a score for [7]: 8
Enter a score for [8]: 20
Enter a score for [0]: 1
Enter a score for [1]: 2
Enter a score for [2]: 3
Enter a score for [3]: 4
Enter a score for [4]: 5
Enter a score for [5]: 6
Enter a score for [6]: 7
Enter a score for [7]: 8
Enter a score for [8]:
....

Так до 20 …

0

Решение

sizeof(scores) размер байта scores объект, который является 5 * sizeof(int), На популярных платформах, которые выдают 20. Итак, вы перебираете от 0 до 19 и получаете доступ к элементам массива, которые не существуют.

Странный вывод, который вы наблюдаете, является не чем иным, как проявлением неопределенного поведения, вызванного доступом к массиву за пределами границ.

Итак, почему вы пытаетесь использовать sizeof(scores) как размер массива?

Есть sizeofоснованный на методе, который может определить размер массива, но он включает деление байтового размера всего массива на байтовый размер одного элемента

sizeof scores / sizeof *scores

И имейте в виду, что это работает только для объектов типа массива (не для указателей).

Кроме того, в современном C ++ вы можете использовать

std::extent<decltype(scores)>::value

определить размер массива.

3

Другие решения

Других решений пока нет …