指針是C語(yǔ)言的靈魂,同時(shí)也是很容易讓人犯錯(cuò)的重難點(diǎn),用錯(cuò)了指針將是一個(gè)災(zāi)難。 指針變量的本質(zhì)是值,這個(gè)特殊的值是一個(gè) 需要注意的是,野指針不是NULL指針,通常NULL指針可以使用if語(yǔ)句來(lái)判斷,但是C語(yǔ)言中沒有任何方法用來(lái)判斷一個(gè)指針是否為野指針! 通常野指針是因?yàn)橹羔樧兞恐斜4娴闹挡皇且粋€(gè)合法的內(nèi)存地址或者指向不可用內(nèi)存的指針而造成的。 而且野指針往往會(huì)造成內(nèi)存越界、段錯(cuò)誤等難以找到的問題,下面分幾種情況來(lái)說(shuō)說(shuō)野指針的由來(lái)。 局部變量不像全局變量那樣,不賦值會(huì)自動(dòng)初始化為0,指針name指向的內(nèi)存空間地址是隨機(jī)的,不能向隨機(jī)地址空間寫數(shù)據(jù)。我們?cè)诙x局部指針變量時(shí)應(yīng)該初始化為NULL,局部變量則初始化為0 malloc申請(qǐng)的堆空間釋放后,意味著把這片內(nèi)存歸還到空閑鏈表,其它程序可以使用這片空間,如果其它程序使用了這個(gè)空間,可能導(dǎo)致其它程序莫名其妙的被關(guān)閉,所以一定要在釋放過后將指針變量的值賦值為NULL。 func函數(shù)被調(diào)用的時(shí)候,棧區(qū)存放了局部數(shù)組p,func返回之后,棧頂指針退出,占用的內(nèi)存已經(jīng)被釋放掉,此時(shí)指針s指向一個(gè)被釋放掉了??臻g,如果棧空間值被修改了,就不會(huì)打印出預(yù)期結(jié)果,s就變成了一個(gè)野指針,所以我們絕對(duì)不要在函數(shù)中返回局部變量和局部數(shù)組的地址。一、什么是野指針?
內(nèi)存地址值
,而合法的內(nèi)存地址包括定義的變量的地址(棧)、malloc函數(shù)申請(qǐng)堆內(nèi)存返回的地址(但未使用free釋放,是在堆空間動(dòng)態(tài)申請(qǐng))二、野指針是怎么來(lái)的?
局部指針變量沒有被初始化
//在win10_64位+vs2017
//來(lái)源:技術(shù)讓夢(mèng)想更偉大
//作者:李肖遙
#include <stdio.h>
#include <string.h>
struct Student
{
char* name;
int number;
};
int main()
{
struct Student s;
strcpy(s.name, 'Lixiaoyao'); // OOPS!
s.number = 99;
return 0;
}使用已經(jīng)釋放過后的指針
//在win10_64位+vs2017
//來(lái)源:技術(shù)讓夢(mèng)想更偉大
//作者:李肖遙
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void func(char* p)
{
printf('%s\n', p);
free(p);
}
int main()
{
char* s = (char*)malloc(5);
strcpy(s, 'Lixiaoyao');//數(shù)組越界
func(s);
printf('%s\n', s); // OOPS!使用已經(jīng)釋放的指針s
return 0;
}指針?biāo)赶虻淖兞吭谥羔樦氨讳N毀
//在win10_64位+vs2017
//來(lái)源:技術(shù)讓夢(mèng)想更偉大
//作者:李肖遙
#include <stdio.h>
char* func()
{
char p[] = 'Lixiaoyao';
return p;
}
int main()
{
char* s = func();
printf('%s\n', s); // OOPS!
return 0;
}進(jìn)行了錯(cuò)誤指針運(yùn)算
//在win10_64位+vs2017
//在win10_64位+vs2017
//來(lái)源:技術(shù)讓夢(mèng)想更偉大
//作者:李肖遙
#include <stdio.h>
void main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,10};
int *p;
for (int *p = &a[9];p >= a;){
*--p = 0;
}
}
聯(lián)系客服