简体   繁体   English

为什么C ++中的数组内容有时未初始化?

[英]why the contents of the array in c++ sometimes is not initialized?

I am reading the book of effective c++, one some pages it says that: 我正在阅读有效的c ++书,其中有几页说:

if you're in the C part of C++ and initialization would probably incur a runtime cost, it's not guaranteed to take place. 如果您使用的是C ++的C部分,并且初始化可能会导致运行时开销,则不能保证会发生这种情况。 If you cross into the non-C parts of C++, things sometimes change. 如果您进入C ++的非C部分,有时情况会发生变化。 This explains why an array (from the C part of C++) isn't necessarily guaranteed to have its contents initialized, but a vector (from the STL part of C++) is. 这就解释了为什么不一定要保证数组(来自C ++的C部分)初始化其内容,而是保证矢量(来自C ++的STL部分)是初始化的。

I wondered why the array which is from c part of c++ is not guaranteed to be initialized, but a vector is? 我想知道为什么不能保证c + +的c部分数组是初始化的,但是向量是可以初始化的? Is not the array from c part is build-in type? c部分的数组不是内置类型吗? but why the vector(from the STL part of C++) guaranteed to be initialized? 但是为什么向量(来自C ++的STL部分)保证被初始化?

Because that's what the standard says. 因为这就是标准所说的。 Very early in the specification of C++, it was decided not to change the way types defined in C worked. 在C ++规范的早期,就决定更改C中定义的类型的工作方式。 So an array ( T[] ) is only initialized if 1) the type T has a constructor, 2) there is an explicit initialization or 3) it has static lifetime. 因此,仅在以下情况下初始化数组( T[] ):1)类型T具有构造函数,2)有显式初始化,或者3)具有静态生存期。 Since std::vector isn't inherited from C, there's no C precedent to be concerned with. 由于std::vector不是从C继承的,因此没有C的先例可以关注。 And since some of the operations you can do on a vector require copying, it has to be initialized. 并且由于您可以对向量执行的某些操作需要复制,因此必须将其初始化。 Copying an uninitialized value is undefined behavior. 复制未初始化的值是未定义的行为。

Note that in C++11, std::array follows the C rules. 请注意,在C ++ 11中, std::array遵循C规则。 (This is done to allow aggregate initialization.) (这样做是为了允许聚合初始化。)

When you define int a[10]; 当您定义int a[10]; (non-statically), then the contents of a are not initialized . (非静态), 则不初始化 a的内容。 That's just how C and C++ are designed. 这就是C和C ++的设计方式。 You didn't ask for it, you don't get it. 您没有要求,您没有得到。 (If you wanted an initialized array, you would have said int a[10](); .) (如果您想要一个初始化的数组,您可能会说int a[10]();

In C++, the class std::vector<int> is designed to always have well-defined semantics, no matter what you do. 在C ++中,无论您做什么,类std::vector<int>被设计为始终具有定义明确的语义。 So when you define std::vector<int> v(10) , you get ten value-initialized (ie zeroed) elements (similar to the second example above). 因此,当您定义std::vector<int> v(10) ,您将获得十个值初始化 (即归零)的元素(类似于上面的第二个示例)。

However, don't-pay-for-what-you-don't-need applies regardless, and the latter is probably poor C++. 但是,不管用什么都不用付钱,无论如何,后者可能是较差的C ++。 What you'd normally use is reserve , which, like in C, creates memory but no objects, and objects are created when needed and require no further allocation: 通常使用的是reserve ,它像C语言一样创建内存,但没有对象,并且在需要时创建对象,不需要进一步分配:

std::vector<int> v;            // no allocation (hopefully)
v.reserve(10);                 // one single allocation

for (int i = 0; i != 10; ++i)
    v.push_back(i);            // no allocations, guaranteed

In a nutshell: C only knows about memory . 简而言之:C只知道内存 C++ separates the notion of storage and objects . C ++将存储对象的概念分开。 This finer-grained model goes along with a richer interface. 此更细粒度的模型带有更丰富的界面。 In C, you simply cannot express the concept of "I may need this storage, but I don't have anything to put into it yet." 在C语言中,您根本无法表达“我可能需要此存储空间,但是我还没有任何内容”的概念。

C++ types like vector are actually classes, and they've got a built-in constructor - a procedure which is automatically called when we are creating a variable of this type, and constructors for STL containers can initialize the variable. vector这样的C ++类型实际上是类,它们具有内置的构造函数-当我们创建此类变量时,该过程会自动调用,并且STL容器的构造函数可以初始化该变量。 And when you are using things which come from C, it is much more simple: all you do when you create a variable is just, broadly speaking, taking some part of memory for your own needs. 而且,当您使用来自C的东西时,它要简单得多:从广义上讲,创建变量时所做的一切只是占用一部分内存以满足您自己的需求。 If there is something in this memory, it will stay there just because creating variable of this type (like a simple array) includes only finding memory for it. 如果该内存中有东西,它将留在那里,仅因为创建此类型的变量(如简单数组)仅包括为其找到内存。

the difference is a C-style array is a language primitive, pretty much like an int or a float, so the rule for those is basically do nothing upon declaration. 区别在于C样式数组是语言的原始语言,非常类似于int或float,因此这些规则基本上在声明时不执行任何操作。

int i;

here, i will take any value that was at this position in memory before. 在这里,我将采用内存中此位置之前的任何值。

But vector (and other STL containers) are objects, and objects have a constructors, that usually do some work. 但是向量(和其他STL容器)是对象,并且对象具有构造函数,通常可以完成一些工作。

std::vector<int> v1(10); //create a vector of 10 ints, not initialized, just like int[10] would do
std::vector<int> v2(10, 0);//create a vector of 10 ints, all initialized to zero.

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

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