野指針に関する議論


定義:
「野ポインタ」はNULLポインタではなく、「ゴミ」メモリへのポインタです.一般的にNULLポインタを誤用することはありません.if文で判断しやすいからです.しかし、「野ポインタ」は危険で、if文は役に立たない.
原因:
野指針の成因は主に3種類ある.
一、ポインタ変数が初期化されていない.任意のポインタ変数は作成されたばかりのときに自動的にNULLポインタにはなりません.デフォルト値はランダムで、むやみに指を指します.したがって、ポインタ変数は作成と同時に初期化されるべきであり、ポインタをNULLに設定するか、合法的なメモリを指すようにします.
二、ポインタpがfreeまたはdeleteされた後、NULLに置かれず、pが合法的なポインタだと勘違いさせる.freeとdeleteの名前はひどく(特にdelete)、ポインタが指すメモリを解放しただけで、ポインタ自体を乾かしたわけではありません.通常は文if(p!=NULL)でエラー防止処理を行います.残念ながらif文は、pがNULLポインタでなくても正当なメモリブロックを指さないため、エラー防止の役割を果たしません.例:
       
#include <stdio.h>   
#include <string.h>    
#include <stdlib.h>
void main()   
{  
	int i;
	char *p = (char *) malloc(100);   
	strcpy(p, "hello");   
	free(p); // p         ,  p            
	if(p != NULL) //            
	   strcpy(p, "world"); //   (  :          )   
	for(i=0;i<5;i++) //i=5       
		printf("%c", *(p+i));
	printf("
");    }

もう1つの注意すべき問題は、関数の終了時にスタックメモリが解放されるため、スタックメモリを指すポインタや参照を返さないでください.
三、ポインタ操作は変数の作用範囲を超えている.このような状況は防ぎきれない.例のプログラムは以下の通りである.
class A   
{   
  public:   
   void Func(void){ cout << “Func of class A” << endl; }   
};   
void Test(void)   
{   
 A *p;   
 {   
  A a;   
  p = &a; //    a      ,        (        ),     test     
 }   
 p->Func(); // p  “   ”   
} 


関数Testは文p->Func()を実行するとオブジェクトaが消え,pはaを指すのでpは「野ポインタ」となる.