【扩展知识4】指针家的野孩子和地址打印

【扩展知识4】

1.        野指针

2.        %p的使用

( 1 )野指针

定义:野指针”不是NULL指针,是指向“垃圾”内存的指针。[重量级危险人物]

野指针的成因:

1.        指针变量定义时没有初始化。

2.        指针变量free后没有置于NULL。

3.        指针的使用超出范围

程序举例:

[ 程序1 ]

//指针变量没有初始化
#include<stdio.h>

int main( void)
{
         char *cp;  //定义char型指针,但是没有初始化。
         int *ip;  //定义int型指针,也没有初始化

         float score;  //float型变量
         float *fp= &score; //定义float指针变量 ,并指向score。

         int num= 10;
         int *ptr1;     //定义int型变量,这里没初始化
         ptr1= #   //让ptr指向变量num的地址.&是取地址符。

         char *pt= NULL;  //一开始就初始化为NULL。

         //以上除了cp、ip是野指针的话,其余的都不是。

    return 0;
}
 

[程序 2 ]

//指针变量free后没有置于NULL
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int n= 100;
         char *ptr;

         ptr= ( char * )malloc( n* sizeof( char ) );  //分配100字节的空间
         if( ptr== NULL )
         {
                   printf( "内存分配失败!\n");

                   exit( 1 );
         }       

         //其他操作省略

         //free释放内存
         free( ptr );  //注意malloc等分配内存函数,必须与free配套使用

         ptr= NULL; //使ptr不是野指针。

    return 0;
}

说明:

Free释放指针后,要把指针赋值为NULL。如果不赋值为NULL(会指向乱码),我们就无法使用if语句判断指针是否为NULL了。

[程序 3 ]

#include <stdio.h>
#include <stdlib.h>  //for malloc,free,exit

#define N 100

//print函数的声明
void print( void );

int main( void )
{
         char*str= NULL;

         str=( char * )malloc( N* sizeof( char ) );
         if(str== NULL )
         {
                   printf("内存分配失败!\n" );

                   exit(1 );
         }

         print(); 

         free(str );
         str=NULL;

         return0;
}

void print( void )
{
         //str越界使用!!!
         strcpy(str, "hello" );

         return;
}

说明:

程序中虽然定义str并为其分配内存,但其作用仅在main中。函数print函数中的str虽然同名,但与main的str却不相同。所以,编译时就报错,print中的str没有定义。

( 2 )%p是什么?

我们可能对常用的%d,%f,%x等比较熟悉吧,对%p却很陌生。其实,%p就是以十六进制打印地址,相当于00%X打印地址。

格式控制符“%p”中的p是pointer(指针)的缩写。指针的值都是一个表示地址空间中某个存储器单元的整数。printf函数族中对于%p一般以十六进制整数方式输出指针的值,附加前缀00。

[程序]

//编译环境:VC++6.0
#include <stdio.h>

int main( void )
{
         intnum;

         printf("%p\n", &num );
   printf( "00%X\n", &num );

         return0;
}

运行结果:

0022FEBC

0022FEBC

【指尖的微笑】错误在所难免,希望得到大家的指正^-^

转载时保留原文的链接http://codingit.howbbs.com和http://blog.csdn.net/mirrorsbeyourself

时间: 2024-10-16 05:49:19

【扩展知识4】指针家的野孩子和地址打印的相关文章

【扩展知识2】函数strlen()和非函数sizeof的使用

[扩展知识2]函数strlen()和非函数sizeof的使用 [扩展目录] strlen函数 sizeof ( 1 )函数strlen() 原型:size_tstrlen ( const char * str ); 返回C字符串(仅仅支持此类型)的长度. //strlen()的使用 #include <stdio.h> int main( void ) { chararray[ ]= "zhijiandeweixiao"; //指尖的微笑 //array为数组的首个地址 p

【扩展知识3】数组的一些难事

[扩展知识3]数组的一些难事 扩展目录 1.        &array+ 1 2.        array+1 3.        &array[ 0 ]+ 1 关于&array+ .array+ 1 和&array[0]+ 1的问题,特别难缠,特难搞懂~-~.所以今天拿来讲解讲解. 由于数组中的各元素的存储单元是连续分配的,因此可以用指针形式来访问数组,数组名就是该数字的首个地址. 如: intarray[100]; array 就是该数组的首地址,其值等于&

【扩展知识3】一些困难的数组

[扩展知识3]一些困难的数组 扩展文件夹 1.        &array+ 1 2.        array+1 3.        &array[ 0 ]+ 1 关于&array+ .array+ 1 和&array[0]+ 1的问题.特别难缠,特难搞懂~-~. 所以今天拿来解说解说. 因为数组中的各元素的存储单元是连续分配的,因此能够用指针形式来訪问数组.数组名就是该数字的首个地址. 如: intarray[100]; array 就是该数组的首地址,其值等于&am

【扩展知识2】学习一些重要的知识

[扩展知识二]学习一些重要的知识 [扩展目录] 1.      布尔型,浮点型.指针的变量与0值得比较 2.      类型转换 3.      关键字sizeof和strlen()函数 A:bool变量与0值得比较 布尔型,用于表示布尔值,即逻辑值TRUE(真)和FALSE (假).在C语言中非零即为真,零就为假. 较合理的写法是: //测试环境:win7_32+VC++6.0.有的编译器可能不识bool //bool变量与0,1的比较 #include <stdio.h> int main

C++基础知识总结--指针

记忆C++的语法很难,光记忆语法也没有用,不如在简单的代码中,体味C++的语法,用实战方式,学习和巩固这些知识.无论有多难的程序,也是由简单的程序组成的,所以,基础知识牢固,才能做出成绩,本着此想法,开始写这篇文章. 一有关指针的基础知识 1.1定义,代码这样实现的: #include <iostream> using namespace std; int main( ) {        int a,b;                                     //定义整型变

038改变状态栏的颜色(扩展知识:关于iOS不同版本的消息通知知识)

效果如下: ViewController.h 1 #import <UIKit/UIKit.h> 2 3 @interface ViewController : UIViewController 4 @end ViewController.m 1 #import "ViewController.h" 2 3 @interface ViewController () 4 - (void)userNotificationDidPush:(UIApplication *)appl

[面试题总结及扩展知识]同一进程中的线程共享的资源

又是一道腾讯2014年的面试题: A,栈   B,数据段    C,寄存器组    D,文件描述符 这是解释以及相对应的扩展知识: 线程的共性如下: 线程共享的环境包括:进程代码段. 进程的公有数据(利用这些共享的数据,线程很容易的实现相互之间的通讯). 进程打开的文件描述符. 信号的处理器.  进程的当前目录和进程用户ID与进程组ID. 线程的个性如下: 1.线程ID     每个线程都有自己的线程ID,这个ID在本进程中是唯一的.进程用此来标识线程. 2.寄存器组的值     由于线程间是并

java Map扩展知识练习

/* map扩展知识. map集合被使用是因为映射关系. 编程实现以下数据: "yureban" -> "01" "zhangsan" "yureban" -> "02" "lisi" "jiuyeban" -> "01" "wangwu" "jiuyeban" -> "02

【扩展知识6】typedef的使用

[扩展知识]typedef的使用 扩展目录 1.        typedef与#define不同处 2.        typedef的使用 A:typedef与#define不同处 typedef是关键字,具有一种高级数据特性,它能够为已经存在的类型重新命别名(标签).它的功能与#define相似,但有3个不同之处:(在<C语言第二回>中也有相关的知识点) 1.        与#define不同,typedef给出的符号仅限于类型,而不是绝对值 2.        typedef的解释有