C++中使用vs2015和g++对new开辟的堆内存是否初始化的分析
在C++中使用new
运算符在堆中申请一内存块的使用权的同时还可以执行对该内存块的初始化工作。下面通过使用2个类对象和2个基本数据类型来分析使用new class_object
、new class_object()
和new int
、new int()
对这块内存的初始化情况。
1 示例程序
这里用下面这个C++程序作为演示,在后面两个小节中分别使用g++和vs2015来编译。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
|
2 使用g++编译器进行编译并执行
无论是否将DEFAULTFUN
的值设置为1(即打开类A中的默认构造函数),在使用g++编译器编译并执行的输出结果都如下图所示。从图中可以看出在使用new
运算符开辟了内存后,会自动对这块内存进行初始化。因此,图中类A的两个对象obj1和obj2对应的数据成员i_value的值都为0,而且整型指针变量指向偏移量为10的那个整数也都是0。
3 在visual studio 2015中进行编译并执行
分别把上面程序中的DEFAULTFUN
的值设置为0和1,也就是测试类中是否包含自定义的构造函数对使用new
运算符开辟内存并初始化的影响,然后在vs2015中进行编译和执行,具体操作和对应结果如下。
3.1 把DEFAULTFUN
的值设置为0
DEFAULTFUN
的值设置为0,然后在visual studio 2015中进行编译并执行,得到的结果如下图所示。对比类A的对象obj1和obj2的数据成员的输出值可以得出结论:如果类A中没有自定义的构造函数,那么new A
和new A()
会调用编译器合成的默认构造函数,但是只有new A()
会对这块内存(各个成员变量)进行初始化(默认为0)。
3.2 把DEFAULTFUN
的值设置为1
DEFAULTFUN
的值设置为1,然后在visual studio 2015中进行编译并执行,得到的结果如下图所示。对比类A的对象obj1和obj2的数据成员的输出值可以得出结论:如果自定义了构造函数,那么不论是new A
还是new A()
都会调用这个构造函数进行初始化(本例为10)。
4 总结
从第2小节的结果可以看出,对于g++编译器来说,无论是使用new class_object
、new class_object()
和new int
、new int()
都会对申请的这块内存进行初始化。
从第3和第4小节的结果可以看出,对于visual studio 2015编译器来说他们对上述new
运算符的操作有不同的结果,具体总结如下:
对于基本数据类型(例如int, char等待)在使用new开辟申请内存空间时,如果使用new data_type[numbers]
不会做内存的初始化操作;而使用new data_type[numbers]()
时除了申请内存空间外还会把这块内存中所有的数据初始化为0。
对于对象类型(例如string以及自定义的类对象等)在使用new开辟申请内存空间时,如果没有自定义构造函数,那么使用new data_type[numbers]
和使用new data_type[numbers]()
都会调用由编译器合成的默认构造函数,但是new data_type[numbers]()
还会把这块内存中所有的数据初始化为0;如果自定义了构造函数,那么使用new data_type[numbers]
和使用new data_type[numbers]()
都会调用由编译器合成的默认构造函数,然后进行初始化(例中为10)。
Comments »