关于C++指针很好的介绍



通过指向类的NULL指针调用类的成员函数
试图用一个null指针调用类的成员函数,导致崩溃:

<code class="hljs cs has-numbering"><span style="font-size:18px;"><span class="hljs-preprocessor">#include <iostream></span>

<span class="hljs-keyword">using</span> namespace std;

class A 
{
    <span class="hljs-keyword">int</span> <span class="hljs-keyword">value</span>;
<span class="hljs-keyword">public</span>:
    <span class="hljs-keyword">void</span> <span class="hljs-title">dumb</span>() <span class="hljs-keyword">const</span> {cout << <span class="hljs-string">"dumb()\n"</span>;}
    <span class="hljs-keyword">void</span> <span class="hljs-keyword">set</span>(<span class="hljs-keyword">int</span> x) {cout << <span class="hljs-string">"set()\n"</span>; <span class="hljs-keyword">value</span>=x;}
    <span class="hljs-keyword">int</span> <span class="hljs-keyword">get</span>() <span class="hljs-keyword">const</span> {cout << <span class="hljs-string">"get()\n"</span>; <span class="hljs-keyword">return</span> <span class="hljs-keyword">value</span>;}
};

<span class="hljs-keyword">int</span> main()
{
    A *pA1 = <span class="hljs-keyword">new</span> A;
    A *pA2 = NULL;

    pA1->dumb();
    pA1-><span class="hljs-keyword">set</span>(<span class="hljs-number">10</span>);
    pA1-><span class="hljs-keyword">get</span>();
    pA2->dumb();
    pA2-><span class="hljs-keyword">set</span>(<span class="hljs-number">20</span>);<span class="hljs-comment">//崩溃</span>
    pA2-><span class="hljs-keyword">get</span>();

        <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}</span></code>

为什么会这样?
通过非法指针调用函数,就相当于给函数传递了一个指向函数的非法指针!
但是为什么pA2->dumb()会成功呢?
因为导致崩溃的是访问了成员变量!!

使用已经释放的指针

<code class="hljs r has-numbering"><span style="font-size:18px;">struct X 
{
    int data;
};

int foo() 
{
    struct X *pX;
    pX = (struct X *) malloc(sizeof (struct X));
    pX->data = <span class="hljs-number">10</span>;     
    free(pX);
        <span class="hljs-keyword">...</span>   
    <span class="hljs-keyword">return</span> pX->data;
}</span></code>

使用未初始化的指针
如果你这样写,编译器会提示你使用了未初始化的变量p。

<code class="hljs perl has-numbering"><span style="font-size:18px;">void fooA()
{
    <span class="hljs-keyword">int</span> <span class="hljs-variable">*p</span>;
    <span class="hljs-variable">*p</span> = <span class="hljs-number">100</span>;
}</span></code>

那么如果我释放一个初始化的指针呢?

<code class="hljs cpp has-numbering"><span style="font-size:18px;"><span class="hljs-keyword">void</span> fooB()
{
    <span class="hljs-keyword">int</span> *p;
    <span class="hljs-built_in">free</span>(p);
}</span></code>

结果是一样的!!

释放已经释放的指针
直接看看代码:

<code class="hljs cpp has-numbering"><span style="font-size:18px;"><span class="hljs-keyword">void</span> fooA() 
{
    <span class="hljs-keyword">char</span> *p;
    p = (<span class="hljs-keyword">char</span> *)<span class="hljs-built_in">malloc</span>(<span class="hljs-number">100</span>);     
    <span class="hljs-built_in">cout</span> << <span class="hljs-string">"free(p)\n"</span>;
    <span class="hljs-built_in">free</span>(p);
    <span class="hljs-built_in">cout</span> << <span class="hljs-string">"free(p)\n"</span>;
    <span class="hljs-built_in">free</span>(p);
}</span></code>

这样的问题也许不会立即使你的程序崩溃,那样后果更加严重!!

没有调用子类的析构函数
之前的博客讲过,父类的析构函数最好声明为虚!!

<code class="hljs r has-numbering"><span style="font-size:18px;">ParentClass *pObj = new ChildClass;
<span class="hljs-keyword">...</span>
delete pObj;</span></code><ul class="pre-numbering" style="display: block;"><li><span style="font-size:18px;">1</span></li><li><span style="font-size:18px;">2</span></li><li><span style="font-size:18px;">3</span></li></ul>

上述代码会造成崩溃,如果父类的析构函数不声明为虚,那么不会调用继承类的析构函数,造成内存泄露。

内存溢出
当我们拷贝字符串的时候,我们常常会用到 memcpy函数。这里特别需要注意的就是字符串结尾的null字符:

<code class="hljs cpp has-numbering"><span style="font-size:18px;"><span class="hljs-keyword">char</span> *p = (<span class="hljs-keyword">char</span> *)<span class="hljs-built_in">malloc</span>(<span class="hljs-built_in">strlen</span>(str));
<span class="hljs-built_in">strcpy</span>(p, str);</span></code>

为了躲过这个坑,只需要把 strlen(str) 改为 strlen(str)+1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值