{ int i;}
main()
{
A a; //这个时候a里面的i是随机值
A *p= new A();//这个时候p里面的i是0
}
所以我可以得出这么一个结论不:
1 )在堆里面申请内存 内存里面的值是“0”值?(
如果1)成立的话 : 2)可是为什么看到有的人会把从堆里面申请的内存memset为0呢? 是不是没有这个必要?
3)在栈里面定义的类的变量 其成员值是随机的?
高手解答下这三个问题
19 个解决方案
#1
补充下 2) 看到有人是malloc一段内存 然后memset为0
#2
分配的地方不一样,new在堆上分配
#3
00415630 push ebp
00415631 mov ebp,esp
00415633 sub esp,100h
00415639 push ebx
0041563A push esi
0041563B push edi
0041563C lea edi,[ebp-100h]
00415642 mov ecx,40h
00415647 mov eax,0CCCCCCCCh
0041564C rep stos dword ptr es:[edi]
0041564E mov byte ptr [ebp-0DDh],0
A a; //这个时候a里面的i是随机值
A *p= new A();//这个时候p里面的i是0
00415655 mov dword ptr [ebp-0F8h],4
0041565F mov eax,dword ptr [ebp-0F8h]
00415665 push eax
00415666 call operator new (41161Dh)
0041566B add esp,4
0041566E mov dword ptr [ebp-0ECh],eax
00415674 cmp dword ptr [ebp-0ECh],0
0041567B je main+73h (4156A3h)
0041567D mov ecx,dword ptr [ebp-0F8h]
00415683 push ecx
00415684 push 0
00415686 mov edx,dword ptr [ebp-0ECh]
0041568C push edx
0041568D call @ILT+1860(_memset) (411749h)
00415692 add esp,0Ch
00415695 mov eax,dword ptr [ebp-0ECh]
0041569B mov dword ptr [ebp-100h],eax
004156A1 jmp main+7Dh (4156ADh)
004156A3 mov dword ptr [ebp-100h],0
004156AD mov ecx,dword ptr [ebp-100h]
004156B3 mov dword ptr [p],ecx
#4
编译器就是这么定的,记住就行了。
#5
学习了
#6
理论上,栈上对象也该调用默认构造函数,但这里没有。int这种内建类型默认设置为0。
同时,堆上也没有调用,只是用了个简单的memset。
同时,堆上也没有调用,只是用了个简单的memset。
#7
class A
{
public:
int i;};
int main(int argc, char *argv[])
{
00415630 push ebp
00415631 mov ebp,esp
00415633 sub esp,10Ch
00415639 push ebx
0041563A push esi
0041563B push edi
0041563C lea edi,[ebp-10Ch]
00415642 mov ecx,43h
00415647 mov eax,0CCCCCCCCh
0041564C rep stos dword ptr es:[edi]
A a = A(); //这个时候a里面的i是随机值
0041564E xor eax,eax #eax 清0
00415650 mov dword ptr [ebp-104h],eax
00415656 mov ecx,dword ptr [ebp-104h]
0041565C mov dword ptr [a],ecx
int i = 1;
0041565F mov dword ptr [i],1
A *p= new A();//这个时候p里面的i是0
00415666 mov dword ptr [ebp-0F8h],4
00415670 mov eax,dword ptr [ebp-0F8h]
00415676 push eax
00415677 call operator new (41161Dh)
0041567C add esp,4
0041567F mov dword ptr [ebp-0ECh],eax
00415685 cmp dword ptr [ebp-0ECh],0
0041568C je main+84h (4156B4h)
0041568E mov ecx,dword ptr [ebp-0F8h]
00415694 push ecx
00415695 push 0
00415697 mov edx,dword ptr [ebp-0ECh]
0041569D push edx
0041569E call @ILT+1860(_memset) (411749h)
004156A3 add esp,0Ch
004156A6 mov eax,dword ptr [ebp-0ECh]
004156AC mov dword ptr [ebp-10Ch],eax
004156B2 jmp main+8Eh (4156BEh)
004156B4 mov dword ptr [ebp-10Ch],0
004156BE mov ecx,dword ptr [ebp-10Ch]
004156C4 mov dword ptr [p],ecx
printf("%d",a.i);
004156C7 mov esi,esp
004156C9 mov eax,dword ptr [a]
004156CC push eax
004156CD push offset string "%d" (4237FCh)
004156D2 call dword ptr [__imp__printf (42850Ch)]
004156D8 add esp,8
004156DB cmp esi,esp
004156DD call @ILT+1290(__RTC_CheckEsp) (41150Fh)
虽然还是没看到代码里有调默认构造函数(也没有临时对象生成),但输出就是0了。
所以你还是应该自己写构造函数。而不是听编译器由命
#8
学习
#9
多谢
#10
Hello * = new hello, 是堆内存分配。分配在你的数据和常量区。 Hello hello 是栈内存分配,分配在你的程序的尾巴部分。
#11
class A
{
int i;
};
A类没有定义构造函数,因为其成员是内置类型的,所以在构造A类对象时,
语言级别上,编译器应该只为其分配空间,不对其成员做任何的初始化,
这在在栈上和堆上创建对象来讲都是一样的,语言级别上来讲,值都应该是随机的
至于楼主所说的在堆上创建对象时,空间被memset过了,这最多算是编译器的扩展,标准中并没有规定
标准中只是说了对于内置类型,支持一种特殊的构造语法,可将对象初始化为0,比如:
int *p = new int();
但是对于类类型来说,加不加最后的()都是一样的,都是调用缺省的构造函数,就像类A,其缺省的构造函数不会对其成员初始化,
楼主可以试下其他的编译器,比如:在VC6中,楼主举的例子不管是在栈上还是在堆上创建的A类的对象,他的成员i的值都是随机的!
#12
class A
{ int i;}
main()
{
A a;
A *p= new A();
}
刚才在DEVC++中试了下,当写为如下形式时:
A *p= new A();//是被memset过的
A *p= new A;//是未被memset过的,值是随机的
搞不清楚了!
#13
学习之 大哥!
#14
(1) 堆中分配的内存按类型的默认构造方法进行初始化,对于内置类型一般为默认值0,对于类类型将调用默认构造函数进行初始化;
(2)对于全局变量同(1),对于局部变量,即栈中变量为随机值
(2)对于全局变量同(1),对于局部变量,即栈中变量为随机值
#15
无论是在栈上,还是堆上开辟的内存,理论上都是随机的,具体可能和编译器有关。所以楼主所提出的说法是不正确的
#16
理论上都是随机的!!!!!楼主慎重,不要找规律!!!
#17
你把下面的A *p=new A();换成A *p=new A;的话你会发现在堆中分配的A也没有被初始化,和栈中分配的A一样。
当在类型后面加上一对括号且没有参数时表示用该类型的默认值初始化,对内置类型就是0。
建议你好好看看the c++ programming language。这是c++之父写的书,看完这本书,很多问题都明白了,另外一本就是C++ Standard - ANSI ISO IEC 14882 2003,这是c++标准。
当在类型后面加上一对括号且没有参数时表示用该类型的默认值初始化,对内置类型就是0。
建议你好好看看the c++ programming language。这是c++之父写的书,看完这本书,很多问题都明白了,另外一本就是C++ Standard - ANSI ISO IEC 14882 2003,这是c++标准。
#18
默认构造函数会把成员初始化,楼主研究的太深了!!
#19
又查了c++ 标准new A;和new A();可能是不同的!
5.3.4.15
A new-expression that creates an object of type T initializes that object as follows:
If the new-initializer is omitted:
if T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-
initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. I T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;
— If the new-initializer is of the form (), the item is value-initialized (8.5);
8.5.5
To value-initialize an object of type T means:
if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
5.3.4.15
A new-expression that creates an object of type T initializes that object as follows:
If the new-initializer is omitted:
if T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-
initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. I T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;
— If the new-initializer is of the form (), the item is value-initialized (8.5);
8.5.5
To value-initialize an object of type T means:
if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
#20
#1
补充下 2) 看到有人是malloc一段内存 然后memset为0
#2
分配的地方不一样,new在堆上分配
#3
00415630 push ebp
00415631 mov ebp,esp
00415633 sub esp,100h
00415639 push ebx
0041563A push esi
0041563B push edi
0041563C lea edi,[ebp-100h]
00415642 mov ecx,40h
00415647 mov eax,0CCCCCCCCh
0041564C rep stos dword ptr es:[edi]
0041564E mov byte ptr [ebp-0DDh],0
A a; //这个时候a里面的i是随机值
A *p= new A();//这个时候p里面的i是0
00415655 mov dword ptr [ebp-0F8h],4
0041565F mov eax,dword ptr [ebp-0F8h]
00415665 push eax
00415666 call operator new (41161Dh)
0041566B add esp,4
0041566E mov dword ptr [ebp-0ECh],eax
00415674 cmp dword ptr [ebp-0ECh],0
0041567B je main+73h (4156A3h)
0041567D mov ecx,dword ptr [ebp-0F8h]
00415683 push ecx
00415684 push 0
00415686 mov edx,dword ptr [ebp-0ECh]
0041568C push edx
0041568D call @ILT+1860(_memset) (411749h)
00415692 add esp,0Ch
00415695 mov eax,dword ptr [ebp-0ECh]
0041569B mov dword ptr [ebp-100h],eax
004156A1 jmp main+7Dh (4156ADh)
004156A3 mov dword ptr [ebp-100h],0
004156AD mov ecx,dword ptr [ebp-100h]
004156B3 mov dword ptr [p],ecx
#4
编译器就是这么定的,记住就行了。
#5
学习了
#6
理论上,栈上对象也该调用默认构造函数,但这里没有。int这种内建类型默认设置为0。
同时,堆上也没有调用,只是用了个简单的memset。
同时,堆上也没有调用,只是用了个简单的memset。
#7
class A
{
public:
int i;};
int main(int argc, char *argv[])
{
00415630 push ebp
00415631 mov ebp,esp
00415633 sub esp,10Ch
00415639 push ebx
0041563A push esi
0041563B push edi
0041563C lea edi,[ebp-10Ch]
00415642 mov ecx,43h
00415647 mov eax,0CCCCCCCCh
0041564C rep stos dword ptr es:[edi]
A a = A(); //这个时候a里面的i是随机值
0041564E xor eax,eax #eax 清0
00415650 mov dword ptr [ebp-104h],eax
00415656 mov ecx,dword ptr [ebp-104h]
0041565C mov dword ptr [a],ecx
int i = 1;
0041565F mov dword ptr [i],1
A *p= new A();//这个时候p里面的i是0
00415666 mov dword ptr [ebp-0F8h],4
00415670 mov eax,dword ptr [ebp-0F8h]
00415676 push eax
00415677 call operator new (41161Dh)
0041567C add esp,4
0041567F mov dword ptr [ebp-0ECh],eax
00415685 cmp dword ptr [ebp-0ECh],0
0041568C je main+84h (4156B4h)
0041568E mov ecx,dword ptr [ebp-0F8h]
00415694 push ecx
00415695 push 0
00415697 mov edx,dword ptr [ebp-0ECh]
0041569D push edx
0041569E call @ILT+1860(_memset) (411749h)
004156A3 add esp,0Ch
004156A6 mov eax,dword ptr [ebp-0ECh]
004156AC mov dword ptr [ebp-10Ch],eax
004156B2 jmp main+8Eh (4156BEh)
004156B4 mov dword ptr [ebp-10Ch],0
004156BE mov ecx,dword ptr [ebp-10Ch]
004156C4 mov dword ptr [p],ecx
printf("%d",a.i);
004156C7 mov esi,esp
004156C9 mov eax,dword ptr [a]
004156CC push eax
004156CD push offset string "%d" (4237FCh)
004156D2 call dword ptr [__imp__printf (42850Ch)]
004156D8 add esp,8
004156DB cmp esi,esp
004156DD call @ILT+1290(__RTC_CheckEsp) (41150Fh)
虽然还是没看到代码里有调默认构造函数(也没有临时对象生成),但输出就是0了。
所以你还是应该自己写构造函数。而不是听编译器由命
#8
学习
#9
多谢
#10
Hello * = new hello, 是堆内存分配。分配在你的数据和常量区。 Hello hello 是栈内存分配,分配在你的程序的尾巴部分。
#11
class A
{
int i;
};
A类没有定义构造函数,因为其成员是内置类型的,所以在构造A类对象时,
语言级别上,编译器应该只为其分配空间,不对其成员做任何的初始化,
这在在栈上和堆上创建对象来讲都是一样的,语言级别上来讲,值都应该是随机的
至于楼主所说的在堆上创建对象时,空间被memset过了,这最多算是编译器的扩展,标准中并没有规定
标准中只是说了对于内置类型,支持一种特殊的构造语法,可将对象初始化为0,比如:
int *p = new int();
但是对于类类型来说,加不加最后的()都是一样的,都是调用缺省的构造函数,就像类A,其缺省的构造函数不会对其成员初始化,
楼主可以试下其他的编译器,比如:在VC6中,楼主举的例子不管是在栈上还是在堆上创建的A类的对象,他的成员i的值都是随机的!
#12
class A
{ int i;}
main()
{
A a;
A *p= new A();
}
刚才在DEVC++中试了下,当写为如下形式时:
A *p= new A();//是被memset过的
A *p= new A;//是未被memset过的,值是随机的
搞不清楚了!
#13
学习之 大哥!
#14
(1) 堆中分配的内存按类型的默认构造方法进行初始化,对于内置类型一般为默认值0,对于类类型将调用默认构造函数进行初始化;
(2)对于全局变量同(1),对于局部变量,即栈中变量为随机值
(2)对于全局变量同(1),对于局部变量,即栈中变量为随机值
#15
无论是在栈上,还是堆上开辟的内存,理论上都是随机的,具体可能和编译器有关。所以楼主所提出的说法是不正确的
#16
理论上都是随机的!!!!!楼主慎重,不要找规律!!!
#17
你把下面的A *p=new A();换成A *p=new A;的话你会发现在堆中分配的A也没有被初始化,和栈中分配的A一样。
当在类型后面加上一对括号且没有参数时表示用该类型的默认值初始化,对内置类型就是0。
建议你好好看看the c++ programming language。这是c++之父写的书,看完这本书,很多问题都明白了,另外一本就是C++ Standard - ANSI ISO IEC 14882 2003,这是c++标准。
当在类型后面加上一对括号且没有参数时表示用该类型的默认值初始化,对内置类型就是0。
建议你好好看看the c++ programming language。这是c++之父写的书,看完这本书,很多问题都明白了,另外一本就是C++ Standard - ANSI ISO IEC 14882 2003,这是c++标准。
#18
默认构造函数会把成员初始化,楼主研究的太深了!!
#19
又查了c++ 标准new A;和new A();可能是不同的!
5.3.4.15
A new-expression that creates an object of type T initializes that object as follows:
If the new-initializer is omitted:
if T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-
initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. I T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;
— If the new-initializer is of the form (), the item is value-initialized (8.5);
8.5.5
To value-initialize an object of type T means:
if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;
5.3.4.15
A new-expression that creates an object of type T initializes that object as follows:
If the new-initializer is omitted:
if T is a (possibly cv-qualified) non-POD class type (or array thereof), the object is default-
initialized (8.5). If T is a const-qualified type, the underlying class type shall have a user-declared
default constructor.
— Otherwise, the object created has indeterminate value. I T is a const-qualified type, or a (possibly
cv-qualified) POD class type (or array thereof) containing (directly or indirectly) a member of
const-qualified type, the program is ill-formed;
— If the new-initializer is of the form (), the item is value-initialized (8.5);
8.5.5
To value-initialize an object of type T means:
if T is a class type (clause 9) with a user-declared constructor (12.1), then the default constructor for T is
called (and the initialization is ill-formed if T has no accessible default constructor);
if T is a non-union class type without a user-declared constructor, then every non-static data member
and base-class component of T is value-initialized;