go语言中有野指针吗 go语言%v( 二 )


参考资料来源go语言中有野指针吗:百度百科-野指针
什么是野指针?野指针go语言中有野指针吗,也就是指向不可用内存区域的指针 。通常对这种指针进行操作的话,将会使程序发生不可预知的错误 。首先请诸位看以下一段“危险”的C++代码go语言中有野指针吗:
void function( void )
{
【go语言中有野指针吗 go语言%v】char* str = new char[100];
delete[] str;
// Do something
strcpy( str, "Dangerous!!" );
}
之所以说其危险,是因为这是一段完全合乎语法的代码,编译的时候完美得一点错误也不会有,然而当运行到strcpy一句的时候,问题就会出现,因为在这之前,str的空间已经被delete掉了,所以strcpy当然不会成功 。对于这种类似的情况,在林锐博士的书中有过介绍 , 称其为“野指针” 。
那么,诸位有没有见过安全的“野指针”呢?下面请看我的一段C++程序,灵感来自CSDN上的一次讨论 。在此,我只需要C++的“类”,C++的其余一概不需要,因此我没有使用任何的C++标准库 , 连输出都是用printf完成的 。
#include stdio.h
class CTestClass
{
public:
CTestClass( void );
int m_nInteger;
void Function( void );
};
CTestClass::CTestClass( void )
{
m_nInteger = 0;
}
void CTestClass::Function( void )
{
printf( "This is a test function.\n" );
}
void main( void )
{
CTestClass* p = new CTestClass;
delete p;
p-Function();
}
OK , 程序到此为止,诸位可以编译运行一下看看结果如何 。你也许会惊异地发现:没有任何的出错信息,屏幕上竟然乖乖地出现了这么一行字符串:
This is a test function.
奇怪吗?不要急,还有更奇怪的呢 , 你可以把主函数中加上一句更不可理喻的:
((CTestClass*)NULL)-Function();
这仍然没有问题?。?
我这还有呢,哈哈 。现在你在主函数中这么写,倘说上一句不可理喻,那么以下可以叫做无法无天了:
int i = 888;
CTestClass* p2 = (CTestClass*)i;
p2-Function();
你看到了什么?是的 , “This is a test function.”如约而至 , 没有任何的错误 。
你也许要问为什么,但是在我解答你之前,请你在主函数中加入如下代码:
printf( "%d, %d", sizeof( CTestClass ), sizeof( int ) );
这时你就会看到真相了:输出结果是——得到的两个十进制数相等 。对,由sizeof得到的CTestClass的大小其实就是它的成员m_nInteger的大小 。亦即是说,对于CTestClass的一个实例化的对象(设为a)而言,只有a.m_nInteger是属于a这个对象的,而a.Function()却是属于CTestClass这个类的 。所以以上看似危险的操作其实都是可行且无误的 。
现在你明白为什么我的“野指针”是安全的了,那么以下我所列出的,就是在什么情况下,我的“野指针”不安全:
在成员函数Function中对成员变量m_nInteger进行操作;
将成员函数Function声明为虚函数(virtual) 。
以上的两种情况,目的就是强迫野指针使用属于自己的东西导致不安全,比如第一种情况中操作本身的m_nInteger,第二种情况中变为虚函数的Function成为了属于对象的函数(这一点可以从sizeof看出来) 。
其实,安全的野指针在实际的程序设计中是几乎毫无用处的 。我写这一篇文章,意图并不是像孔乙己一样去琢磨回字有几种写法,而是想通过这个小例子向诸位写明白C++的对象实例化本质,希望大家不但要明白what和how,更要明白why 。李马二零零三年二月二十日作于自宅 。

推荐阅读