当前位置: 首页 > news >正文

学习做网站的淘宝关键词搜索

学习做网站的,淘宝关键词搜索,wordpress wp_nav_menu,在家给别人做网站合法吗目录 1、野指针 1.1 野指针的成因 1.指针未初始化 2.指针越界访问 3.指针指向的空间释放 1.2 野指针的危害 1.3 如何规避野指针 1. 指针初始化 2. 小心指针越界 3.指针变量不使用就及时赋上NULL 4. 指针使用前检查是否是空指针 5. 避免返回局部变量的地址 1.4 区…

c1e7d05d4e2741879502cdc4427804b7.jpeg

目录

1、野指针

1.1 野指针的成因

1.指针未初始化

2.指针越界访问

3.指针指向的空间释放

1.2 野指针的危害

1.3 如何规避野指针

1. 指针初始化

2. 小心指针越界

3.指针变量不使用就及时赋上NULL

4. 指针使用前检查是否是空指针 

5. 避免返回局部变量的地址

1.4 区分野指针和空指针

2、assert断言

2.1 定义与用法

2.2 assert优点:

2.3 assert使用场景:


 

本篇文章将带来野指针的介绍,野指针与空指针的区分,以及assert断言


1、野指针

什么是野指针呢?

野指针就是指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)

举个例子:你想去朋友家(访问内存中的数据),但你拿的地址(野指针)是错的,可能是个还没建好的房子的地址,也可能是个已经拆掉的房子的地址,这时候你就找不到朋友家了,还可能会惹出麻烦。

1.1 野指针的成因

1.指针未初始化

#include <stdio.h>
int main()
{int* p;//局部变量未初始化,默认未随机值*p = 20;return 0;
}

由于指针p未初始化,所以*p就属于非法访问,p就是野指针。

对比一下初始化后的指针:

#include <stdio.h>
int main()
{int n = 100;int* p = &n;//已初始化的指针*p = 20;printf("%d", n);return 0;
}

2.指针越界访问

#include <stdio.h>
int main()
{int arr[10] = { 0 };//0 0 0 0 0 0 0 0 0 0(10个数)int* p = &arr[0];int i = 0;for (i = 0; i <= 11; i++);//循环了12次{*p = i;p++;}printf("%d", n);return 0;
}

越界还是很好理解的,前面也有多次提到,比如这里数组只有10个元素,但是循环却循环了12次,这样就会造成最后两次循环生成的是随机数。

也就是说,当指针指向的范围超出数组arr的范围时,p就是野指针

3.指针指向的空间释放

#include <stdio.h>
int* test()
{int n = 100;//n是局部变量return &n;
}
int main()
{int* p = test();printf("%d", *p);return 0;
}

可以看出上面的代码有上面问题吗?

上诉代码中,n是局部变量,所以n的生命周期就是局部范围,当出了范围后,n会被销毁。通过

return &n导致n的地址被返回。p接收了这个地址。在&n返回的时候,n所占的空间就不属于n了。

这时候p在拿着刚才返回的地址去找n,根本找不到。因此,当p得到地址的时候,就已经是野指针了!

举个例子辅助理解一下:

假设你在图书馆租了一个存包柜来放你的书包(这就相当于在内存中分配了一块空间来存储数据)。然后你把书包放进去,存包柜上的号码牌就像是指针,它能让你找到放书包的位置。

当你要离开图书馆的时候,你把书包取走了(这就相当于释放了指针所指向的空间),这个存包柜就空了,不再属于你使用。

但是,如果之后你还拿着那个号码牌(也就是还保留着那个指针),想要再去开这个柜子放东西或者取东西,那就不行啦,因为这个柜子已经不再为你服务,它可能已经被分配给其他人使用,或者干脆被图书馆收回了。这就相当于在程序中,对已经释放的空间进行操作,会导致错误。

1.2 野指针的危害

使用野指针可能导致程序崩溃、数据损坏、系统不稳定等严重问题

举个例子:(该例子只是为了说明野指针的危害,没有实际意义)

比如说你是一个快递员,你的任务是根据地址把包裹送到指定的人家。

正常情况下,每个地址都是清晰准确的,你能顺利地完成送货任务。但如果地址写错了,比如写成了一个不存在的门牌号(这就好比野指针),那麻烦就大了。

你可能会在错误的地方一直找,浪费大量的时间和精力(就像程序在错误的内存位置寻找数据,导致程序运行效率降低)。

或者你可能不小心把包裹放到了别人的家门口,造成包裹送错(这就如同程序错误地修改了不该修改的数据,导致数据出错)。

更糟糕的是,如果这个错误的地址指向了一个敏感的区域,比如是警察的办公地点或者是银行的金库(在程序中就是关键的系统区域),那可能会引起大麻烦,甚至会触犯法律(在程序中可能导致系统崩溃或者出现严重的安全漏洞)。

1.3 如何规避野指针

1. 指针初始化

如果明确知道指针指向哪里就直接赋值地址,如果不知道指针应该指向哪里,可以给指针赋值NULL.

NULL是C语言中定义的一个标识符常量,值是0,0也是地址,这个地址是无法使用的,读写该地址会报错

#include <stdio.h>
int main()
{int n = 10;int* p = &n;//有明确的指向int* p2;//野指针return 0;
}

上诉代码中p指针有明确的指向对象n,而p2则是野指针,为了防止野指针的危害,但又因为没具体的指向,因此可以给p2赋上NULL初始化。

#include <stdio.h>
int main()
{int n = 10;int* p = &n;//有明确的指向int* p2 = NULL;//初始化NULLreturn 0;
}

当赋上NULL后,虽然p2指针无法使用,但是我们可以很好的将p2这个野指针管理起来,野指针你可以把它比作一条野狗,如果不拴起来会有很大的危害(未初始化),而拴起来后只要不去招惹它就不会出现问题(给野指针赋上NULL ,且不使用它) 

2. 小心指针越界

我们向内存申请了哪些空间,通过指针野就只能访问哪些空间,不能超出范围访问,超出了就是越界访问因此。在使用的时候需要格外注意!

3.指针变量不使用就及时赋上NULL

当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问。

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];for(int i = 0;i < 10;i++){*(p++) = i;}//循环结束后p就不在使用了,可以将p设置为NULLp = NULL;return 0;

4. 指针使用前检查是否是空指针 

 使用指针之前可以判断指针是否为NULL。如果是NULL,就不使用该指针。

#include <stdio.h>
int main()
{int n = 10;int* p = &n;int* p2 = NULL;if (p2 != NULL)//在使用前判断p2是否为空指针{//……}return 0;
}

5. 避免返回局部变量的地址

局部变量在函数结束后其内存会被释放,如果返回其地址,就会得到一个野指针。如上述野指针成因的第三种其情况。

1.4 区分野指针和空指针

野指针和空指针是两个不同的概念,主要区别如下:

定义

  • 空指针是被明确赋值为 NULL (在 C 或 C++ 中)的指针,表示它不指向任何有效的内存地址。
  • 野指针是指向一个不确定的、无效的或者未分配的内存地址的指针。

安全性

  • 空指针的使用是相对安全的,因为在程序中对空指针进行解引用操作通常会导致程序崩溃,从而能够让开发者意识到问题所在。
  • 野指针的使用则非常危险,因为它可能指向任意的内存位置,对其解引用可能导致不可预测的错误,甚至破坏重要的数据。

产生原因

  • 空指针通常是由开发者主动将其赋值为 NULL 来表示某种特殊情况或未初始化的状态。
  • 野指针通常是由于编程错误,比如指针未初始化、指针所指向的内存被释放后未正确处理等原因产生的。

举例说明:

// 空指针
int *p = NULL;  // 这是一个明确的空指针// 野指针
int *p;  // 未初始化,可能成为野指针
int arr[5];
int *p = &arr[5];  // 超出数组范围,成为野指针

2、assert断言

2.1 定义与用法

assert 断言是一种在编程中用于调试和验证假设的工具。

assert.h 头文件定义了宏 assert() ,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”。

assert(p != NULL);

//表达式为真,继续运行

//表达式为假,程序停止

上面代码在程序运行到这一行语句时,验证变量 p 是否等于 NULL 。如果确实不等于NULL,程序就继续运行,否则就会终止运行,并且给出报错信息提示。 

 代码展示:

#include <stdio.h>
int main()
{int* p = NULL;assert(p != NULL);return 0;
}

结果:

5c5ae6f15c9e4d58b1b4df1097c170d2.png

assert() 宏接受⼀个表达式作为参数。如果该表达式为真(返回值非零),assert()不会产生任何作用,程序继续运行。如果该表达式为假(返回值为零), assert()就会报错,在标准错误流stderr 中写入⼀条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。

2.2 assert优点

  1. 自动标识文件和出问题的代码的行数
  2. 使代码的逻辑更加清晰,明确了开发者对代码执行过程中的预期。
  3. 无需更改代码就能开启或关闭assert()的机制。如果已经确定程序没问题,只需要在#include <assert.h> 前面定义宏 NDEBUG.

#define NDEBUG //加上这一行就可以关闭assert断言
#include <assert.h>
int main()
{
    int* p = NULL;
    assert(p != NULL);
    return 0;
}

2.3 assert使用场景

  1. 检查函数的输入参数是否符合预期。
  2. 验证在特定代码段中某些关键变量的状态或值。

assert 断言在开发和测试阶段特别有用。它能帮助您快速发现那些您认为“绝对不应该发生”的情况,让您更快地找到并修复代码中的错误。

但要记住,在最终发布给用户的程序中,assert通常会关闭断言,因为它会带来一些额外的性能开销。不过在开发过程中,它可是您的好帮手,能大大提高代码的质量和可靠性。


结语:
本篇文章到这里就结束了,如果觉得还不错的话,就麻烦各位给小编一个三连吧!!!

 

http://www.dt0577.cn/news/13155.html

相关文章:

  • 高密做网站哪家好代理成都高薪seo
  • 海外做代购去哪个网站校园推广的方式有哪些
  • 东莞市精神建设委员会网站怎么在网上做广告
  • 网站空间网站虚拟空间石家庄网站seo外包
  • 网站做拓扑图编辑我要软文网
  • 广东一站式网站建设费用举一个网络营销的例子
  • 学摄影的网站有哪些一个企业seo网站的优化流程
  • 如何网站开发如何策划一个营销方案
  • 手机网站模板用什么做搜索引擎营销分类
  • 做网站功能模块网络推广属于什么行业
  • 深圳品牌网站制作公司哪家好软文网官网
  • 重庆网站APP直通车关键词优化
  • 新网站制作平台百度首页
  • 网站建设需要集齐哪5份资料今日国内新闻大事件
  • 武汉快速推广建站公司网络推广项目
  • 020网站建设和维护费用湖南企业seo优化首选
  • 建简单网站网站需要怎么优化比较好
  • 平顶山建设街小学网站seo的搜索排名影响因素有
  • 清华紫光做网站广州优化seo
  • 怎么样自己开网站荨麻疹怎么治疗能除根
  • 福建建设工程交易网站灰色行业怎么推广引流
  • 建设银行广西分行招聘网站网站建设的流程是什么
  • 网络营销策划案框架长沙seo招聘
  • 邯郸网站建设生活中的网络营销有哪些
  • 滕州网站设计什么公司适合做seo优化
  • 好的网站设计培训机构推广策划方案模板
  • 网站后台打开慢鞍山seo优化
  • 免费网站建站排行榜安装百度到桌面
  • 王晴儿 网站建设seo推广知识
  • 厦门seo关键词优化代运营临沂做网络优化的公司