为什么int数组在C ++中没有初始化为零?

时间:2012-08-04 23:15:13

标签: c++ arrays initialization

我在C ++中有一个基本程序,它列出了给定数量的素数。完成工作的类是下面的 - 我的问题是,当“amount”的输入为10(特别是10 - 它适用于我尝试过的所有其他数字)时,下面生成的数组未初始化为一个零的数组。因此,“数组的最后一个元素为空”返回false,并且我的代码无法正常运行。

我不知道我是否误解了,但不应该将int数组初始化为零?如果没有,整数10有什么特别之处,导致它初始化为奇怪的值?

int* primecalc(int amount) {

int* primes = new (nothrow) int [amount];

//Throw an error if we can't allocated enough memory for the array.
if (primes==0) {
cout<< "Error allocating memory.";
return 0;
}

//Otherwise, start iterating through the numbers.
else {
primes[0] = 2;
primes[1] = 3;

int p = 2;

for (int i=4;primes[amount]==0;i++) {
int j = 0;
int k = 0;

    while ((primes[j]<=floor(i/2)) && !(primes[j]==0) && (k==0)) {

        if ((i % primes[j]) == 0) {
        k=1;
        } 
    j++;
    } //end the while loop

if (k==0) {
        primes[p] = i;
        p++;

}

} //end the for loop

} //end the "else" part (this was only necessary in case memory could not be allocated)

return primes;
}

我也试过没有(nothrow),结果相同。在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:13)

int* primes = new (nothrow) int[amount];正在使用默认初始化,对于像int这样的标量是noop(即没有执行实际的初始化)。

如果要进行显式初始化,请改为使用 value-initialization

int* primes = new (nothrow) int[amount]();

来自C ++ 11标准,§8.5/ 6:

  

默认初始化 T类型的对象意味着:

     
      
  • 如果T是(可能是cv限定的)类类型,则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化格式不正确);
  •   
  • 如果T是数组类型,则每个元素都默认初始化;
  •   
  • 否则,不执行初始化
  •   
     

如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型。

第8.5节/ 7:

  

value-initialize T类型的对象意味着:

     
      
  • 如果T是具有用户提供的构造函数的(可能是cv限定的)类类型,则调用T的默认构造函数(如果T没有,则初始化是错误的access default constructor);
  •   
  • 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T隐式声明的默认值构造函数是非平凡的,该构造函数被调用。
  •   
  • 如果T是数组类型,则每个元素都是值初始化;
  •   
  • 否则,该对象为零初始化
  •   
     

值初始化的对象被视为构造,因此受本国际标准的规定适用于“构造”对象,“构造函数已完成的对象”等,即使没有调用构造函数也是如此用于对象的初始化。

第8.5节/ 6:

  

零初始化 T类型的对象或引用意味着:

     
      
  • 如果T是标量类型,则将对象设置为值0(零),作为整数常量表达式,转换为T
  •   
  • 如果T是一个(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;
  •   
  • 如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员将进行零初始化,并将填充初始化为零位;
  •   
  • 如果T是数组类型,则每个元素都是零初始化;
  •   
  • 如果T是引用类型,则不执行初始化。
  •   

最后来自§8.5/ 10:

  

一个对象,其初始化程序是一组空的括号,即(),应进行值初始化。

(所有强调我的。)

答案 1 :(得分:3)

这只是为了提高效率。并非在所有场合都必须预先填充数组,因此默认情况下C ++不会这样做。

如果你使用std::vector<int>而不是普通数组(我建议你),你有一个构造函数来设置一个可以为0的初始值:

std::vector<int> v(10,0);  // 10 elements with 0