通过指向类的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