空指针也不崩溃-转载

本文深入探讨了在C++中通过未初始化的空指针调用成员函数的行为,分析了不同情况下程序的稳定性和崩溃原因。从成员函数是否使用成员变量、静态变量的使用,到继承与虚函数的调用,全面解析了潜在的内存访问错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.sina.com.cn/s/blog_532f6e8f01017ljb.html

 

class A

{

public:

int m_iA1;

void print()

{

cout << "A" << endl;

}

};

int main()

{

A *pObjectA=NULL;

pObjectA->print();

return 0; 

}

 

*a没有初始化,结果成功输出“A”。

分析:成员函数在代码段,成员变量在数据段,地址为在类对象地址基础上累加。

此处的print成员函数没有用到成员变量,与类外独立函数无异。调用的时候不涉及数据段,不会崩溃。

 

如果成员函数print中使用到了成员变量,情况会是怎样呢?

class A

{

public:

int m_iA1;

char m_chA2;

void print()

{

m_iA1 = 1;

cout << "A" << endl;

}

};

int main()

{

A *pObjectA=NULL;

pObjectA->print();

return 0; 

}

编译执行后,崩在了print函数中的红色标记语句。

分析:此处的print成员函数用到成员变量m_iA1,我们可以看到,&pObjectA=0x00000000,&m_iA1=0x00000000,&m_iA2=0x00000004

空指针也不崩溃
访问了非法地址,崩溃了

 

尝试给pObjectA分配空间后,&pObjectA=0x003b6060,&m_iA1=0x003b6060,&m_iA2=0x003b6064,

空指针也不崩溃

这是合法的数据段地址,访问成功。

 

我们再给A类加一点有趣的东西来验证一下

1、static静态变量

class A

{

public:

static int m_iSA4;

static void print()

{

m_iSA4 = 4;

cout << "A" << endl;

}

};

int A::m_iSA4 = 0;

 

int main()

{

A *pObjectA=NULL;

pObjectA->print();

return 0; 

}

 

运行成功!静态变量独立于类外部分配好了合法地址,访问成功。

 

2、继承

class B

{

int m_iB1;

public:

virtual void print()

{

cout << "B" << endl;

}

};

 

class A:public B

{

    int m_iA1;

    char m_chA2;

public:

    void print()

    {

        cout << "A" << endl;

    }

};

 

int main()

{

    A *pObjectA=NULL;

    pObjectA->print();

    return 0; 

}

 

运行之后崩在在main函数的红色标记语句。

分析:虽然A类的print函数没有用到显式的成员变量,但是类A继承于类B,print()是继承于B的虚函数,调用A的print函数时,用到了虚表,虚表地址在类对象数据段最开头,此时访问了非法地址。

可以看到成员变量地址:

空指针也不崩溃
 

给pObjectA分配空间之后再看

空指针也不崩溃
 

可以看到,在继承类对象的地址空间中的顺序为:虚表指针、基类成员变量、继承类成员变量

 

通常崩溃报错的对话框中会给出一些关键信息:

空指针也不崩溃
如此图中的0x00411596表示出错的代码段地址,0xC0000000为出错的数据段地址,0xC0000005为错误码。“Access violation”就是此错误码的具体含义,查看所有错误码含义可查阅Visual Studio-Debug-Exceptions-Win32 Exceptions。详细错误信息都会保存在dmp文件中,用Windbg这类工具可以看到详细信息,进行具体分析。

一、C语言自我YY1)、C语言是许多高级计算机语言的基础,学好C语言能更好的学习其他高级语言,为以后的学习打基础;往深学C语言的话那就是学到C在Linux里的应用,Linux十分强大。2)、C语言是一种计算机程序设计语言。具有高级语言的特点,又具有汇编语言的特点。C语言可作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写依赖计算机硬件的应用程序。3)、应用范围广泛,具备很强的数据处理能力,仅仅是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件,三维,二维图形和动画。具体应用比如单片机以及嵌入式系统开发。4)、C语言是面向过程语言,C语言通过windows/linux平台下编译的,是直接运行在windows/linux平台下的,而XX始终是运行在他的虚拟机之上的;所以理论上C语言能做一些相对于比较底层的工作,像XX就能编写Windows病毒。5)、如果要利用编程来做一些windows优化工作的话,建议还是利用C语言。C语言是目前世界上流行、使用最广泛的高级程序设计语言6、很多编译器,几乎所有操作系统Windows,Linux,Unix的大部分代码都是C,C在背后做了很多东西的,也许开发游戏用C++,安卓用XX更为合适,图形界面的用其他语言开发效率更高一些(因为他们封装了很多东西),但同样的原因导致略微接近底层的功能其他语言根本干了!Windows的API都是按照C语言的格式给的,这也很能说明问题!嵌入式开发更是离了C语言!纵观电脑发展几十年,C语无所能呀!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值