Record08—野指针问题;向空指针NULL拷贝数据报错;连续更改指针指向;字面量问题

目录

野指针问题

向NULL空间拷贝数据报错

不断改变指针指向

字面量问题

总体代码


野指针问题

void main11()
{

	char  *p1 = NULL;
	p1 = (char *)malloc(100);
	if (p1 == NULL)
	{
		return ;
	}
	strcpy(p1, "11112222");

	printf("p1:%s \n", p1);

	if (p1 != NULL)
	{
		free(p1);  //手动释放堆区的内存空间
		//p1 = NULL;
	}

	//

	if (p1 != NULL)
	{
		free(p1);
	}

	printf("hello...\n");
	system("pause");
	return ;
}

首先补充一下free函数的用法,“void free(void *ptr)”,free里面放的是一个指针变量,就可以把这个指针变量指向的内存中所存放的内容给析构了。(我原来以为应该传入一个指针变量所指向的空间(*p)呢,没想光传一个指针变量就行了!)

这个程序会报错。这是因为,在第一次free(pl)的时候,只是手动的把位于堆区的内容给擦除掉了,而存放在变量pl中的值(这个值就是存放在堆区的内容的存放内存空间的首地址)并没有改变,当第二次调用free(pl);的时候,pl就变成了一个野指针,因为没有它仍旧保存着原先的内容,而在堆区对应的地址位置的内容早就被擦除了,于是就报错了。正确纠正这种情况的方法是,在第一次free(pl)后,加一条“p1 = NULL;”,人工的把pl中存放的值给初始化,然后才方便进行后续的操作。示意图如下:

野指针产生的原因:
1)指针变量和它所指向的内存空间变量是两个不同的概念
2)释放了指针所致的内存空间  但是指针变量本身没有重置成null
3)造成释放的时候 通过if (p1 != NULL)

避免方法:

1)定义指针的时候 初始化成nuLL

2)释放指针所指向的内存空间后,把指针重置成NULL。

向NULL空间拷贝数据报错

举个例子

void main01()
{

	char *p1 = NULL;

	strcpy(p1, "abcdefg");
	printf("hello...\n");
	system("pause");
	return ;
}

设置一个指针变量p1,初始值设置为NULL,然后,往里面拷贝数据,发现出现报错:

这是因为, NULL所占用的操作系统的内存空间(0开始的那个内存空间的位置),是受操作系统保护的区间,里面的应用程序不能随便的往里面写。同理,是不是不是NULL就行了?看下面这个:

void main02()
{

	char *p1 = NULL;
	p1 = 0x00077;

	strcpy(p1, "abcdefg");
	printf("hello...\n");
	system("pause");
	return ;
}

当把p1的指向更改为0x00077的时候,是不是就不会报错了呢?

还是报错,这说明,当向0开头的内存空间拷贝数据或者进行操作的时候,都会 报错,这是因为0开头的这段内存空间是被操作系统保护的!不可被修改。

不断改变指针指向

针对不断改变指针指向的内存空间,下面做三个版本的示例:

先定义好几个指针,

void main22()
{
	char	buf[128]; //c可以在栈上分配内存
	int		i; 
	int     j = 0;

	char	*p2 = NULL; //c可以在栈上分配内存

	char *p1 = NULL;

  


	printf("hello...\n");
	system("pause");
	return ;
}

版本一,直接更改指向。

	p1 = &buf[0]; //不断的修改p1的值 相当于 不断改变指针的指向
	p1 = &buf[1];
	p1 = &buf[2];

版本二,用一个循环来更改。

    for (i=0; i<10; i++)
	{
		p1 = buf[i];
	}

版本三,在堆区开一个内存空间,再来更改指向这个空间的指针。

	p2 = (char *)malloc(100);
	strcpy(p2, "abcdefg1212333333333311");

	for (i=0; i<10; i++)
	{
		p1 = p2+i;
		printf("%c ", *p1);
	}

 最后,用示意图示意如下,

点睛:通过指针调用在内存中存放的不同内存空间的值,这就是C的精华所在!

字面量问题

想象一下之前遇到的情况:

int a = 0;
int b = "abcdef";
int c = buf[10];

问,变量a,b,c对应的值分别放在了内存四区的那个区?

答:c很明显,是在栈区直接开辟了10个单位的区域来存放内容;b也很明显是在全局区,开辟了区域来存放,字符常量。唯一有争议的就是a了,那a的值具体放在那个区,很有争议,只能说a的那“0”值,是个字面量,肯定是不会放在栈区和堆区的。如果非要回答的话,就是放在了代码区中了!

总体代码

dm01_习题.c



#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

//野指针产生的原因
//指针变量和它所指向的内存空间变量是两个不同的概念
// 释放了指针所致的内存空间  但是指针变量本身没有重置成null
//造成释放的时候 通过if (p1 != NULL)

//避免方法: 1)定义指针的时候 初始化成nuLL 2)释放指针所指向的内存空间后,把指针重置成NULL。
void main11()
{

	char  *p1 = NULL;
	p1 = (char *)malloc(100);
	if (p1 == NULL)
	{
		return ;
	}
	strcpy(p1, "11112222");

	printf("p1:%s \n", p1);

	if (p1 != NULL)
	{
		free(p1);
		p1 = NULL;
	}

	//

	if (p1 != NULL)
	{
		free(p1);
	}

	printf("hello...\n");
	system("pause");
	return ;
}

 dm02_铁律1强化.c

#define  _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

void main01()
{

	char *p1 = NULL;

	strcpy(p1, "abcdefg");
	printf("hello...\n");
	system("pause");
	return ;
}

void main02()
{

	char *p1 = NULL;
	p1 = 0x00077;

	strcpy(p1, "abcdefg");
	printf("hello...\n");
	system("pause");
	return ;
}

void main22()
{
	char	buf[128]; //c可以在栈上分配内存
	int		i; 
	int     j = 0;

	char	*p2 = NULL; //c可以在栈上分配内存

	char *p1 = NULL;

	p1 = &buf[0]; //不断的修改p1的值 相当于 不断改变指针的指向
	p1 = &buf[1];
	p1 = &buf[2];

	for (i=0; i<10; i++)
	{
		p1 = buf[i];
	}

	p2 = (char *)malloc(100);
	strcpy(p2, "abcdefg1212333333333311");

	for (i=0; i<10; i++)
	{
		p1 = p2+i;
		printf("%c ", *p1);
	}

	printf("hello...\n");
	system("pause");
	return ;
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值