一級指針-野指針
三隻小熊66 2016-12-04 21:12:28 199 收藏
展開
一級基礎指針的使用
基礎使用
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *p = NULL;//一級指針
p = (char *)malloc(100 * sizeof(char));
strcpy(p, "abcdefg");
printf("%s\n", p);
system("pause");
return 0;
}
我們能夠正常的分配堆內存中有有一個100個字節的內存空間,裏面放着一個字符串abcdefg。如果有條件的話以後會把內存四區圖給大家奉獻上來。
釋放內存出現野指針
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *p = NULL;//一級指針
p = (char *)malloc(100 * sizeof(char));
strcpy(p, "abcdefg");
printf("%s\n", p);
if (p != NULL)
{
free(p);
}
//如果在進行釋放就會出現野指針
if (p != NULL)
{
free(p);
}
//本質就是指針變量和指針所指向的變量是完全不同的
system("pause");
return 0;
}
基本解決野指針的方案
1.初始化指針的時候要爲NULL
2.釋放的時候要判斷指針是否爲NULL
3.釋放完以後我們要把指針賦值爲NULL
代碼如下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char *p = NULL;//一級指針
p = (char *)malloc(100 * sizeof(char));
strcpy(p, "abcdefg");
printf("%s\n", p);
if (p != NULL)
{
free(p);
p = NULL;
}
//如果在進行釋放就會出現野指針
if (p != NULL)
{
free(p);
}
//本質就是指針變量和指針所指向的變量是完全不同的
system("pause");
return 0;
}
看在作爲函數參數的時候
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *createMem()
{
char *p = NULL;//1.首先爲NULL
p = (char *)malloc(100 * sizeof(char));
strcpy(p, "abcdefg");//賦值
printf("%s\n", p);
return p;
}
void freeMem(char *pMem)
{
if (pMem != NULL)//第二步
{
free(pMem);
pMem = NULL;//第三部
}
}
int main()
{
char *pMalloc = NULL;//一級指針
pMalloc = createMem();
freeMem(pMalloc);
freeMem(pMalloc);
system("pause");
return 0;
}
上面的基本上是沒有問題,但是我們在把freeMem在調用一遍發現程序崩潰了。
核心改變實參
以上我們看到出現問題的核心就在於我雖然在函數內對指針進行的賦值爲NULL,但是外部的實參根本沒有變化,所以我們想起來在函數當中如果要修改外部的參數使用地址的方式來進行操作最簡單的就是一級指針修改一個0級指針就是我們所謂的一般性的變量數據。
#include <stdio.h>
#include <stdlib.h>
void choose(int a)
{
a = 20;
}
int main()
{
int b = 10;
choose(b);
printf("%d\n", b);
system("pause");
return 0;
}
我們可以看到打印的數據仍然是10不會修改成20,其實如果大家還不會看內存四區的話,其實你打印a的地址,你會發現他是一個新的地址,意思就是說根本和實參沒有任何的關係,是新開闢的一層空間,如果我們想修改b的數據,我們可以用到指針,然後把地址傳入到函數裏面進行修改,代碼入股下:
#include <stdio.h>
#include <stdlib.h>
void choose(int *a)
{
*a = 20;
}
int main()
{
int b = 10;
choose(&b);
printf("%d\n", b);
system("pause");
return 0;
}
改成這樣我們發現數據發生了改變,這就是指針存在的意義。然後我們返回去看看剛纔發生的錯誤和這個很類似,於是我們進行修改一下看看代碼如下:
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
//野指針產生問題分析
//指針變量和它所指內存空間變量是兩個不同的概念
//解決野指針的方案
//1定義指針時 把指針變量賦值成null
//2 釋放內存時,先判斷指針變量是否爲null
//3 釋放內存完畢後,把指針變量重新賦值成null
char *getMem2(int count)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
return tmp;
}
//實參和形參是兩個不同的概念
void getMem3(int count, char *p)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
p = tmp;
}
void getMem4(int count, char **p /*out*/)
{
char *tmp = NULL;
tmp = (char *)malloc(100 * sizeof(char)); //char tmp[100];
*p = tmp;
}
//函數調用的時候,這個場景修改不實參
int FreeMem2(char **p)
{
if (p == NULL)
{
return -1;
}
if (*p != NULL)
{
free(*p);
*p = NULL; //想把實參給改掉,你能修改嗎? 修改不了實參。。。。。
}
return 0;
}
void main()
{
char *myp = NULL;
myp = getMem2(100);
getMem3(100, myp);
getMem4(100, &myp);
FreeMem2(&myp);
FreeMem2(&myp);
system("pause");
}
終於大功告成。希望這樣分段講解能對一些初級朋友有所幫助,如果有什麼問題可以一起討論。以上所有的程序都是在VS上編譯並且通過。
————————————————
版權聲明:本文爲CSDN博主「三隻小熊66」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/sanzhixiong86/article/details/53456238