一级指针-野指针
三只小熊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