C ++数组初始化

时间:2010-02-23 13:51:10

标签: c++

考虑到这一点:

typedef struct
{
 int x;
 int y;
} Coordinate;

Coordinate places[100];
  • 是否自动分配了100个坐标的内存?或者,在初始化数组的每个元素时,它是否一次分配一个?

  • 如果您添加阵列中未初始化的部分,会发生什么?这会触发错误吗?

7 个答案:

答案 0 :(得分:2)

如何保留内存取决于声明数组声明的位置。如果它在全局范围内声明(即在函数外部),那么800字节(假设整数是32位长)立即可用于整个程序。如果它在函数内部,则这些800字节在堆栈上分配,并且在函数退出时不可访问。

所以问题1:是的,整个100坐标与声明的范围相同。

问题2:您可以随时访问所有100个元素,但其内容将未被初始化。所以立即写入所有100个索引是安全的,只是在你初始化之前不要读取它们。

如果您希望将它们全部初始化(比如0,0),请改为声明:

struct Coordinate
{
    int x;
    int y;

    Coordinate () : x(0), y(0) { }
};

当然,这只适用于C ++。如果您使用C编写代码,则无法自动初始化数组中的元素。

在0到99的范围之外读取将给出未定义的行为。充其量,运行时将检测到给您一个运行时错误。在最坏的情况下,你将破坏内存,并且在程序完成之前不会知道,让你想知道错误在哪里。所以要小心,确保你的指数在界限范围内。

通常的做法是提供一个访问数组的函数(不要直接访问数组),你可以在那里进行断言检查以测试数组索引。

祝你好运

答案 1 :(得分:0)

1 /是,有分配。并且在块的末尾调用和释放析构函数。

2 /使用默认构造函数初始化数组的所有元素(如果没有默认构造函数,则为编译时错误)。如果默认构造函数没有初始化某些东西,那么如果该对象是否是数组的一部分,那么它是相同的行为(即未读取的值如果被读取则会导致未定义的行为)

答案 2 :(得分:0)

首先:是的,该区域是保留的,但是在区域正确初始化之前,其内容将无效 第二:很多事情都可能发生,一个是访问冲突或什么都没有,但是让你的系统错误地运行

答案 3 :(得分:0)

内存会自动分配到堆栈中,因此您必须注意阵列的大小。每个操作系统都有不同的堆栈大小,但仍有一个限制。通常每个线程/进程只有少量KB。

当您访问数组的未初始化成员时,您将从另一个堆栈框架或该内存页面中的任何随机垃圾中读取之前的任何内容。因此,使用memset或数组初始化程序初始化数组是一种很好的做法。

答案 4 :(得分:0)

在您的示例中,所有实例都是一次性分配的 - 所有项目0到99都是有效的。如果你使用了带有构造函数的类型,则将构造所有100个。

编辑 - 正如其他人所说,仅仅是因为它的构建并不意味着任何事情已被初始化。 “int”的默认构造函数使它保持不变(这是你的工作,将它初始化为你想要的任何东西)。 “struct”的默认构造函数为其成员调用构造函数。也就是说,构建在这里意义不大 - 但是内存已经分配并准备好(初始化和)使用。

第一个未初始化的“数组的一部分”不是数组的一部分 - 它超出了界限。例如......

Coordinate mistake = places [100];  //  Above the upper bound

这是“未定义”的行为。您可能会遇到崩溃(处理器中某种与内存相关的异常)。你的程序可以继续愉快地工作,不知道它正在使用无效的垃圾数据。在上面的例子中,由于发生的事情是相当明显的,你可能会得到编译器警告 - 但通常情况并非如此。

如果你到一个越界数组索引,你可能会破坏其他变量或函数的返回地址或几乎任何东西,所以整个程序的行为就是那个点以后是未定义的。这是最大类安全漏洞和“漏洞”之一的基础。

std :: vector是另一种创建数组的方法。它不会立即分配所有项目 - 它是一个动态数组,允许(和管理)调整大小。但是,它不会像基本的C风格数组那样捕获越界索引。

答案 5 :(得分:0)

1)将内存分配为单个连续块。

2)如果静态实例化(即不是auto变量),则应将存储器初始化为零,否则它将是未初始化的,并且内容应是未定义的。访问这些未定义的值不会触发任何错误,如果您读取垃圾数据并对其进行操作,行为将完全由非确定性内容决定,以及您的代码对其执行的操作。

如果要自动初始化,可以定义默认构造函数。在C ++中,struct几乎与一个类相同(不同之处在于默认成员可见性和继承),并且可以包含成员函数,构造函数和析构函数。

答案 6 :(得分:0)

基于类型的阵列行为没有区别。 因此,一旦创建数组并且未初始化的变量将有一些垃圾数据,就会完成内存分配。

要初始化数组的所有元素,您可以使用默认构造函数将它们初始化为所需的值或具有默认参数的构造函数,其中值可以初始化为未提供任何值时所需的值。

例如:

struct Coordinate
{ 
    int x;
    int y;

    Coordinate (int x1 = 0, int y1 = 0) : x(x1), y(y1) { } 
};

这适用于数组,数组中的所有值都将初始化为零(0)。

初始化基本数据类型数组的所有元素为零(0)

int places[100] = { 0 };

但是没有验证它是否适用于用户定义的类型。你可以尝试一下。