目录
野指针问题
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 ;
}