在类中初始化时奇怪和不正确的C++中的数组大小行为

问题描述:

我想创建一个名为Player的类,它有一个名为scores的数组,在Player类属性中声明了一个大小。然而,当我初始化一个新玩家时,sizeof(分数)方法给了我20,事实上,它确实初始化了一个大小为20而不是5的得分数组。我想知道为什么以及如何解决这个问题。这里是代码和输出。在类中初始化时奇怪和不正确的C++中的数组大小行为

#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 ...

sizeof(scores)scores对象,这是5 * sizeof(int)的字节大小。在流行的平台上,会产生20个。所以,你从0到19迭代并访问不存在的数组元素。

您观察到的奇怪输出只不过是由出界数组访问引起的未定义行为的表现。

那么,你为什么试图使用sizeof(scores)作为数组大小?

有一个sizeof为基础的技术,可以判断数组大小,但它由一个单一的元素

sizeof scores/sizeof *scores 

的字节大小涉及到整个阵列的字节大小的划分和记住它仅适用于数组类型的对象(不适用于指针)。

替代地,在现代C++可以使用

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

确定数组大小。

+0

或者,使用'std :: array',它有'size'成员函数。 :-) – templatetypedef

+0

我感谢你的建议。为了简单起见,我简单地用“(sizeof(scores)/ sizeof(* scores)”替换了所有“sizeof(scores)”的事件,这很好地起作用。 –