為啥能使用一個野指針(迷途指針)????


# include <iostream>
using namespace std;

class A
{
public:
A(){int n=5; p=&n;}//構造完畢n被釋放,p指向不可用的空間
int * get(){return p;}
private:
int * p;
};

int main(void)
{
A a;
int * x = a.get();
*x = 12345678;
cout << *x << endl;

return 0;
}

p是不是野指針??

21 个解决方案

#1


如果這個地址剛好不在使用,是可以訪問的,但是這樣寫太危險,保不准啥時候就掛了

#2


當有指針型成員變量p時 是不是只能在構造函數中這樣定義:p=new int;用其他任何方法都是錯誤的?

#3


也可以外部傳進去,但你要保證它只被釋放一次

#4


不想程序段錯誤你就別用

#5


沒人說不能用野指針呀!只是野指針存在的問題太多。隨時,可以發生你想不到的錯誤!

#6


其實電腦開機后物理內存的每個字節都是可讀寫的,從來不會因為所謂的new、delete或malloc、free而被創建、銷毀。區別僅在於操作系統內存管理模塊在你讀寫時是否能發現並是否采取相應動作而已。操作系統管理內存的粒度不是字節而是頁,一頁通常為4KB。

#7


這個千萬別這么做。

#8


P是野指針,這個就像你申請了一塊內存: int * ptr = new int[10]; 然后delete[] ptr; 不進行賦值NULL,ptr也是野指針。但是你下次使用時就有好多問題。體會一下。

#9


引用 5 樓 qq_15033289 的回復:
沒人說不能用野指針呀!只是野指針存在的問題太多。隨時,可以發生你想不到的錯誤!

請問大神什麼是野指針??

#10


引用 9 樓 aa5566f4 的回復:
Quote: 引用 5 樓 qq_15033289 的回復:

沒人說不能用野指針呀!只是野指針存在的問題太多。隨時,可以發生你想不到的錯誤!

請問大神什麼是野指針??

就像吃飯以后懶得洗碗一樣 說不准哪天你的碗里產生病菌讓你down了 這個碗就是野指針

#11


打個比方說:偷來的東西吧也確實是真的東西,所以也能用幾下子,就是難免會被警察扣住把東西隨時沒收,你就麻煩了。
例如你可以偷一些石頭打個地基,然后美滋滋蓋自己的樓房,結果某天苦主直接把石頭要回去了你還無法阻止,於是樓塌了。

#12


為什么能使用野指針
首先指針僅是一個保存地址的變量, 而這個指針指向的地址是哪里, 編譯的時候編譯器是不知道的. 所以編譯器不會報錯.
然后運行的時候那就是不確定, 如果正好指向一個可以訪問的合法內存, 那你去讀寫都沒有問題, 如果不可訪問, 那就會出現常見的.

xxx內存不能為read   等等錯誤,

就有點像規定垃圾要扔進垃圾箱,  但很多人仍然還是扔在地上.

#13


垃圾要扔進垃圾箱,  但很多人仍然還是扔在地上,  但扔在地上並不范法

#14


引用 9 樓 aa5566f4 的回復:
Quote: 引用 5 樓 qq_15033289 的回復:

沒人說不能用野指針呀!只是野指針存在的問題太多。隨時,可以發生你想不到的錯誤!

請問大神什麼是野指針??


指針指向對象引用(也就是一個內存地址)。訪問的時候,會根據指針提供的地址,作為對象的首地址,讀取 sizeof(對象類型)個字節,這就是這個引用對象的占用內存。
野指針是指分配了內存但是卻再也沒有辦法引用的指針。

int *p;
p=NULL; //指針賦空后,就變成空指針,不引用任何對象
int n=*p;  //空指針引用(解除引用前沒有判斷是否為空指針)

m=5;
int *p=new int ;//p引用一個int
p=&m; //p重新指向m,這時候上面 new int 那個內存空間就無法引用或刪除了。這個內存的指針就是野指針。

正確的做法應該是: 先把指針賦空,再引用其他對象。對指針解除引用(即訪問引用對象的數據)前,先判斷是否為空指針。
m=5;
int *p=new int ;//p引用一個int
p=NULL;
p=&m; //p重新指向m

if(p!=NULL) m=*p; 
而直接m=*p; 這是很危險的,你不了解上下文,不確定p有沒有引用對象

#15


嚴謹點,應該是:
先把delete p 或free(p)釋放內存地址,然后p=NULL;指針賦空,再p=&m;引用其他對象。if(p!=NULL) m=*p; 對指針解除引用(即訪問引用對象的數據)前,先判斷是否為空指針。

#16


引用 2 樓 okokpypy 的回復:
當有指針型成員變量p時 是不是只能在構造函數中這樣定義:p=new int;用其他任何方法都是錯誤的?


不一定啊,看需要;
1 . 通常做法應該是在初始化類表中初始化為NULL,構造函數里你可以做new動作賦值;
2. 如果覺得里面做new有崩潰的危險,導致類型沒有構建完成,釋放內存的時候會沒法釋放,可以單獨建立個init之類的函數,單獨來調用;
3. 釋放一般放在析構函數里,做釋放就行了;

以上問題,如果還要牽扯多線程什么的,問題就復一些;,比如析構函數可能被做兩次啥的,崩潰就來了。
簡單的就上面所的用法吧。

#17


野指針使用的后果應該是 “行為未定義” 吧,不是說不能用,只是說造成什么后果不知道;

貌似,你new一個對象delete后,他是野的了吧,你訪問它的函數(不訪問成員的)還不會崩潰呢。

#18


當你把一個指針被delete之后沒有賦值為NULL或者創建指針之后沒有初始化,這個指針就成了野指針,這樣做很危險,很可能導致程序出錯。

#19


野指針是delete之后,沒有置空,以至於指針還是指向原來的位置(此時可能已被其他程序占用),這里好像也沒涉及到吧

#20


引用 14 樓 zhi_ai_yaya 的回復:
Quote: 引用 9 樓 aa5566f4 的回復:

Quote: 引用 5 樓 qq_15033289 的回復:

沒人說不能用野指針呀!只是野指針存在的問題太多。隨時,可以發生你想不到的錯誤!

請問大神什麼是野指針??


指針指向對象引用(也就是一個內存地址)。訪問的時候,會根據指針提供的地址,作為對象的首地址,讀取 sizeof(對象類型)個字節,這就是這個引用對象的占用內存。
野指針是指分配了內存但是卻再也沒有辦法引用的指針。

int *p;
p=NULL; //指針賦空后,就變成空指針,不引用任何對象
int n=*p;  //空指針引用(解除引用前沒有判斷是否為空指針)

m=5;
int *p=new int ;//p引用一個int
p=&m; //p重新指向m,這時候上面 new int 那個內存空間就無法引用或刪除了。這個內存的指針就是野指針。

正確的做法應該是: 先把指針賦空,再引用其他對象。對指針解除引用(即訪問引用對象的數據)前,先判斷是否為空指針。
m=5;
int *p=new int ;//p引用一個int
p=NULL;
p=&m; //p重新指向m

if(p!=NULL) m=*p; 
而直接m=*p; 這是很危險的,你不了解上下文,不確定p有沒有引用對象



蟹蟹大神 很詳細

#21


A(){int n=5; p=&n;}//構造完畢n被釋放,p指向不可用的空間

未必是不可用。 p指向了未知空間, 不在掌控之中, 后果危險。 

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com