C Language Study - 错误的指针初始化方式

本文测试指针初始化的方式:

错误初始化方式一:

int* p = NULL;//此句等于p = NULL;将指针指向了NULL这个地址,(NULL=0x0)

*p = 0x10;//试图访问0x0内存,被拒绝

错误初始化方式二:

int* p;//定义的时候未进行初始化,此时指针指向一块未知的内存

*p = 0x10;//试图访问未知内存,被拒绝

那么指针到底如何初始化?

初始化方式参考一:

首先定义一个相应类型的变量,我们称之为指针初始化变量,它的作用

就是用来进行指针初始化的,或者程序中可以对它进行其他的利用。

int pinit = 0;

int* p = &pinit;//初始化指针,这个时候p指针就指向了变量pinit的内存地址

是一块合法的地址

初始化方式参考二:

在参考方式一中,首先定义了一个整型变量,那么我们可以事先获取它的地址

&pinit 我在Code::Blocks上测试的地址是0x22ff18

int* p = (int*)0x22ff18;//当然,这个地址绝对是合法地址,针对不同的编译器,

//我建议多预留几个字节也可以

*p = 0x10;//便可冠冕堂皇地访问该内存

这样就省去了一个整型变量的定义,有一种很高端的感觉,有木有?

初始化方式参考三:

int* p = NULL;//其实这个初始化方式不能说错,但是我们要警惕自己写出这样的代码

如果不小心会发生什么意外状况,你得清楚这块内存是不可访问的(赋值),但是,可以用

指针来指向它,正如你看到一条项链,你用手指指着它了,但是你不能去买。

在上述初始化后,在以后的程序里,在你要使用这个指针之前,先做一下检测:

if(NULL==p)

{

p = &var1//var1:一个拥有合法地址的你想去访问的变量,这样就能使得p指向一个合法地址了

}

else

{

p = &var2//var2:一个拥有合法地址的你想去访问的变量,这样就能使得p指向一个合法地址了

}

另外一种的检测方式:

assert(NULL!=p);//也就是断言,如果NULL!=p(条件为真)程序就会继续运行,否则(条件为假)终止运行。

这样,如果断言发挥了做用,我们就知道错误出现在哪里了,可以及时的修正bug

总结:最终还是得让指针指向一块合法的可以访问的内存。

时间: 2024-08-05 22:09:18

C Language Study - 错误的指针初始化方式的相关文章

C Language Study - 结构体成员指针初始化

结构体成员指针初始化 不可以正确运行的初始化方式(1): #include <stdio.h> #include <string.h> #include <malloc.h> //#include "a.h" //char a[100]; struct stu { char* name; int num; }*pst,st; void init_pst() { pst = (struct stu *)malloc(sizeof(struct stu)

C正确初始化方式

无论是int 还是 char 初始化方式都是一样 (指定初始值或者用指针指向所开辟的内存) int num[] = {1,22,333}; int *p = num; int *num2 = new int[3]; char c[] = {'aaa','a'}; char *cp = c; char *cArr = new char[2];

004--C++11的初始化方式

还有另一种初始化方式,这种方式用于数组和结构体,但在C++98中,也可用于单值变量: int hamburgers={24}; 将大括号初始化器用于单值变量的情形还不多,但C++11标准使得这种情形更多了.首先,采用这种方式时,可以使用等号(=),也可以不使用: int emus{7}; int rheas={12}; 其次,大括号内可以不包含任何东西.在这种情况下,变量将被初始化为零: int rocs={}; int psychics{}; 第三,这有助于更好地防范类型转换错误.

指针初始化

引用: https://blog.csdn.net/qq_43574794/article/details/84864349 https://baike.baidu.com/item/%E6%8C%87%E9%92%88%E5%88%9D%E5%A7%8B%E5%8C%96/3527092#1 --- int i=10: int * a = &i; int * a = NULL;(编译没问题,运行错误,指针所指向地址必须为合法有效的内存地址) a = (int *)malloc(sizeof(i

C Language Study - the use of symbol &#39;##&#39;

## #include <stdio.h> #define INTVARIABLE(n) i##n int main(void) { int INTVARIABLE(2) = 3; printf("i2=%d\n",i2);//output i2=3 i2 = 5; printf("i2=%d\n",i2);//output i2=5 return 0; } C Language Study - the use of symbol '##'

C Language Study - how to use &#39;#&#39;

宏中的#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号. 如定义好#define STRING(x) #x之后,下面二条语句就等价. char *pChar = "hello"; char *pChar = STRING(hello); 还有一个#@是加单引号(Charizing Operator) #define makechar(x)  #@x char ch = makechar(b);与ch

C Language Study - 0 &amp; &#39;0&#39; &amp; &#39;\0&#39;

The difference of 0 & '0' & '\0' ------------------------------------------------------------ 0 is a number(decimal). ------------------------------------------------------------ '0' is a char. It's ASCII equal  48(decimal). ----------------------

自制Javascript分页插件,支持AJAX加载和URL带参跳转两种初始化方式,可用于同一页面的多个分页和不同页面的调用

闲话部分 最近闲着实在无聊,就做了点小东西练练手,由于原来一直在用AspNetPager进行分页,而且也进行了深度的定制与原有系统整合的也不错,不过毕竟是用别人的,想着看自己能试着做出来不能,后台的分页插件已经有比较成熟的了,那就自己试着写一个前台分页吧. 话不多说,先上效果图: 优点与缺点 来说说优缺点吧,首先AspNetPager是后台分页控件,所以在向客户端回传HTML文档之前生成HTML阶段 就会把分页代码生成完毕,然后回传,而JS是前端代码,就是HTML文档在服务器组织完毕往客户端传送

HashMap优雅的初始化方式以及引申

小记 相信很多人和笔者一样,经常会做一些数组的初始化工作,也肯定会经常用到集合类.假如我现在要初始化一个String类型的数组,可以很方便的使用如下代码: String [] strs = {"Tom","Jack"}; 但是我相信很多人在初始化HashMap的时候是使用如下的方式: Map<String, Object> map = new HashMap<String, Object>(); map.put("name"