struct student{
void fun(){
m_i = 0;
b=1;
cout<<m_i<<endl;
cout<<b<<endl;
}
int b;
static int m_i;
};
int student::m_i =0;
int main(void)
{
student *m_p;
m_p->fun();
cout<<m_p<<endl;
cout<<m_p->b<<endl;
getchar();
return 0;
}
m_p只是个指向student类型的指针.还没开辟空间
为什么程序 m_p->fun()和m_p->b 不会崩溃?
18 个解决方案
#1
在vc6上挂了!你的是什么编译器?
#2
木有崩溃是 编译器和os合伙骗你的结果。
看我博客吧
深入探索c/c++函数(2)---普通成员函数调用的基本过程
http://blog.csdn.net/demon__hunter/article/details/5397906
看我博客吧
深入探索c/c++函数(2)---普通成员函数调用的基本过程
http://blog.csdn.net/demon__hunter/article/details/5397906
#3
不要迷信编译器的运行结果,尤其用编译器来验证这些存在 未定义行为的代码。
#4
会挂的 只是编译器不给你看罢了
#5
怎么可能不崩阿...这么奇怪...
#6
因为开始看到腾讯面试的那一贴.
他的原代码为
他的原代码为
struct student{
void fun(){
m_i = 0;
b=1;
cout<<m_i<<endl;
}
static int m_i;
};
int student::m_i =0;
int main(void)
{
student *m_p = 0;
m_p->fun();
return 0;
}
说程序不会崩溃.结果我在C++ BUILD 上测既然真没崩溃.
结果我崩溃了,所以来请教
#7
1、无论多么复杂的类,在计算机执行的时候总是要变成内存中的一段数据。
2、由于m_p没有初始化,所以可能是一个野指针,指向位置未定义。
3、如果未定义的地址恰好足够解释这个类(虽然不是被预期的),那么就不会崩溃。
如果这个地址恰巧不能解释(边界、访问违例),就崩溃了。
4、还和不同的编译器的处理方式有关,有的崩有的不崩,主要依赖编译器制造者对这个问题的处理态度、策略。
~~~~学习啊____
2、由于m_p没有初始化,所以可能是一个野指针,指向位置未定义。
3、如果未定义的地址恰好足够解释这个类(虽然不是被预期的),那么就不会崩溃。
如果这个地址恰巧不能解释(边界、访问违例),就崩溃了。
4、还和不同的编译器的处理方式有关,有的崩有的不崩,主要依赖编译器制造者对这个问题的处理态度、策略。
~~~~学习啊____
#8
xue xi a
#9
student *m_p;没有初始化。某处内存里的值被改写了,没蹦是你运气差
#10
这里b都没声明,能编译过???
#11
void fun(){
m_i = 0;
cout<<m_i<<endl;
}
如果这样子,没蹦的理由是没有用到this指针。m_i是静态成员变量,属于类,不属于对象
fun编译后其实是
fun(student *this)
{
m_i = 0;
this->b=1; // 此处用了this
...
}
m_p->fun()
编译器翻译为
fun(mp)
#12
刚才是那个b忘记删了.
"m_p->fun()
编译器翻译为
fun(mp)"
这段解析主要是因为编译器了?
m_p为野指针.按道理m_p->fun()就应该崩的把
#13
编译器也不能相信啊
#14
编译后,没有类这个概念了。
student::fun()这个函数,编译后和c里的fun(student *this)差不多。函数调用不会只用m_p指针,而是把指针作为一个参数(this)传入。如果函数里没有使用this指针,也就是没用到m_p,那就不会有任何问题。
如果类里有虚函数,那类有个隐含的成员变量 虚指针vptr。那就是另一种情况了。调用函数前,先要使用vptr找到对应的函数,即用到了m_p。
#15
不管什么变量(包括指针变量),没有初始化之前不要用它,这是纪律!
#16
明白了,谢谢.
是不是所有的编译器都会把
m_p->fun()
翻译为
fun(mp)???
还是只是一部分?
#17
不崩不代表正常,不死不代表健康!
#18
没有初始化的指针不要用啊,这也是java去掉指针的一个原因。虽然繁琐,但是还是要做,否则会很麻烦
#1
在vc6上挂了!你的是什么编译器?
#2
木有崩溃是 编译器和os合伙骗你的结果。
看我博客吧
深入探索c/c++函数(2)---普通成员函数调用的基本过程
http://blog.csdn.net/demon__hunter/article/details/5397906
看我博客吧
深入探索c/c++函数(2)---普通成员函数调用的基本过程
http://blog.csdn.net/demon__hunter/article/details/5397906
#3
不要迷信编译器的运行结果,尤其用编译器来验证这些存在 未定义行为的代码。
#4
会挂的 只是编译器不给你看罢了
#5
怎么可能不崩阿...这么奇怪...
#6
因为开始看到腾讯面试的那一贴.
他的原代码为
他的原代码为
struct student{
void fun(){
m_i = 0;
b=1;
cout<<m_i<<endl;
}
static int m_i;
};
int student::m_i =0;
int main(void)
{
student *m_p = 0;
m_p->fun();
return 0;
}
说程序不会崩溃.结果我在C++ BUILD 上测既然真没崩溃.
结果我崩溃了,所以来请教
#7
1、无论多么复杂的类,在计算机执行的时候总是要变成内存中的一段数据。
2、由于m_p没有初始化,所以可能是一个野指针,指向位置未定义。
3、如果未定义的地址恰好足够解释这个类(虽然不是被预期的),那么就不会崩溃。
如果这个地址恰巧不能解释(边界、访问违例),就崩溃了。
4、还和不同的编译器的处理方式有关,有的崩有的不崩,主要依赖编译器制造者对这个问题的处理态度、策略。
~~~~学习啊____
2、由于m_p没有初始化,所以可能是一个野指针,指向位置未定义。
3、如果未定义的地址恰好足够解释这个类(虽然不是被预期的),那么就不会崩溃。
如果这个地址恰巧不能解释(边界、访问违例),就崩溃了。
4、还和不同的编译器的处理方式有关,有的崩有的不崩,主要依赖编译器制造者对这个问题的处理态度、策略。
~~~~学习啊____
#8
xue xi a
#9
student *m_p;没有初始化。某处内存里的值被改写了,没蹦是你运气差
#10
这里b都没声明,能编译过???
#11
void fun(){
m_i = 0;
cout<<m_i<<endl;
}
如果这样子,没蹦的理由是没有用到this指针。m_i是静态成员变量,属于类,不属于对象
fun编译后其实是
fun(student *this)
{
m_i = 0;
this->b=1; // 此处用了this
...
}
m_p->fun()
编译器翻译为
fun(mp)
#12
刚才是那个b忘记删了.
"m_p->fun()
编译器翻译为
fun(mp)"
这段解析主要是因为编译器了?
m_p为野指针.按道理m_p->fun()就应该崩的把
#13
编译器也不能相信啊
#14
编译后,没有类这个概念了。
student::fun()这个函数,编译后和c里的fun(student *this)差不多。函数调用不会只用m_p指针,而是把指针作为一个参数(this)传入。如果函数里没有使用this指针,也就是没用到m_p,那就不会有任何问题。
如果类里有虚函数,那类有个隐含的成员变量 虚指针vptr。那就是另一种情况了。调用函数前,先要使用vptr找到对应的函数,即用到了m_p。
#15
不管什么变量(包括指针变量),没有初始化之前不要用它,这是纪律!
#16
明白了,谢谢.
是不是所有的编译器都会把
m_p->fun()
翻译为
fun(mp)???
还是只是一部分?
#17
不崩不代表正常,不死不代表健康!
#18
没有初始化的指针不要用啊,这也是java去掉指针的一个原因。虽然繁琐,但是还是要做,否则会很麻烦