简体   繁体   English

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

[英]Why is int array not initialized to zeros in C++?

I have a basic program in C++ which lists a given number of primes. 我有一个C ++基本程序,它列出了给定数量的素数。 The class which does the work is below - my question is, when the input for "amount" is 10 (specifically 10 - it works fine for all other numbers I've tried), the array that is generated just below is not initialized to an array of zeros. 完成工作的类是下面的 - 我的问题是,当“amount”的输入为10(特别是10 - 它适用于我尝试过的所有其他数字)时,下面生成的数组未初始化为一个零的数组。 Hence, "the last element of the array is empty" returns false, and my code does not get to run properly. 因此,“数组的最后一个元素为空”返回false,并且我的代码无法正常运行。

I don't know whether I've misunderstood, but shouldn't the int array initialize to zeros? 我不知道我是否误解了,但不应该将int数组初始化为零? If not, what is special about the integer 10 which causes it to initialize to strange values? 如果没有,整数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;
}

I also tried without (nothrow), with the same result. 我也试过没有(nothrow),结果相同。 Thanks in advance for any help! 在此先感谢您的帮助!

int* primes = new (nothrow) int[amount]; is using default-initialization , which for scalars like int is a noop (ie no actual initialization is performed). 正在使用默认初始化 ,对于像int这样的标量是一个noop(即没有执行实际的初始化)。

If you want explicit initialization, use value-initialization instead: 如果要显式初始化,请使用值初始化

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

From the C++11 standard, §8.5/6: 从C ++ 11标准,§8.5/ 6:

To default-initialize an object of type T means: 默认初始化 T类型的对象意味着:

  • if T is a (possibly cv-qualified) class type, the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor); 如果T是(可能是cv限定的)类类型,则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
  • if T is an array type, each element is default-initialized ; 如果T是数组类型,则每个元素都是默认初始化的 ;
  • otherwise, no initialization is performed . 否则,不执行初始化

If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor. 如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型。

§8.5/7: 第8.5节/ 7:

To value-initialize an object of type T means: 类型T的对象进行值初始化意味着:

  • if T is a (possibly cv-qualified) class type with a user-provided constructor, then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor); 如果T是具有用户提供的构造函数的(可能是cv限定的)类类型,则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
  • if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T 's implicitly-declared default constructor is non-trivial, that constructor is called. 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数。
  • if T is an array type, then each element is value-initialized ; 如果T是数组类型,那么每个元素都是值初始化的 ;
  • otherwise, the object is zero-initialized . 否则,该对象被零初始化

An object that is value-initialized is deemed to be constructed and thus subject to provisions of this International Standard applying to “constructed” objects, objects “for which the constructor has completed,” etc., even if no constructor is invoked for the object's initialization. 值初始化的对象被视为构造,因此受本国际标准的规定适用于“构造”对象,“构造函数已完成的对象”等,即使没有为该对象调用构造函数也是如此。初始化。

§8.5/6: 第8.5节/ 6:

To zero-initialize an object or reference of type T means: 零初始化 T类型的对象或引用意味着:

  • if T is a scalar type, the object is set to the value 0 (zero), taken as an integral constant expression, converted to T ; 如果T是标量类型,则将对象设置为值0 (零),作为整数常量表达式,转换为T ;
  • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits; 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;
  • if T is a (possibly cv-qualified) union type, the object's first non-static named data member is zero-initialized and padding is initialized to zero bits; 如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员被零初始化,并且填充被初始化为零位;
  • if T is an array type, each element is zero-initialized ; 如果T是数组类型,则每个元素都是零初始化的 ;
  • if T is a reference type, no initialization is performed. 如果T是引用类型,则不执行初始化。

And finally from §8.5/10: 最后来自§8.5/ 10:

An object whose initializer is an empty set of parentheses, ie, () , shall be value-initialized. 初始值为空集括号的对象,即() ,应进行值初始化。

(All emphasis mine.) (都强调我的。)

It is done just for efficiency. 这只是为了提高效率。 Not in all occasions arrays have to be pre-filled with a value, so C++ does not do it by default. 并非在所有场合都必须预先填充数组,因此默认情况下C ++不会这样做。

If you use std::vector<int> instead of plain arrays (I recommend you to), you have a constructor to set an initial value that can be 0: 如果你使用std::vector<int>而不是普通数组(我建议你),你有一个构造函数来设置一个可以为0的初始值:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM