4986|21

6366

帖子

4929

TA的资源

版主

楼主
 

MSP430单片机调试经验汇总1 [复制链接]

 
数组越界引起的程序溢出
我经常犯这样的错误,定义数组的时候,数组的长度设定的不足,导致程序中向数组赋值时,超出了数组的长度,导致程序溢出。这种程序溢出一般出现在函数结尾处,也就是说,在调试程序时,如果出现在函数结尾发生了程序跑飞的现象,首先查一下是否有数组越界的问题。

最新回复

nice  详情 回复 发表于 2017-7-9 11:57
 
点赞 关注(1)

回复
举报

6040

帖子

205

TA的资源

版主

推荐
 
ywlzh 发表于 2017-7-7 09:29
在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论

楼主的问题是不定长度的数组怎么防 ...[/quote]

[quote]在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论
这种不靠谱的做法,我一眼能看得出来,还至于去编译一下吗?
int ar[3] = {1,2,3,NULL}; 数组长度4写成3当你是笔误,这些都不细讨论了,我针对你后面的回复做下评论:


你基本功略显欠缺,即使你基本功不欠缺,那么你写代码的风格也可以说是极差


NULL一般用于指针,从你去掉的注释看,你也是懂点的,虽然其本质是0,但是你放到数组里当整数用,会不会产生警告暂且不说,这种代码是晦涩难懂的,你直接写成0多直观,何必拐个歪?


""[0]这种委婉的写法,你说写成NULL会有警告,你直接写成0好不好?暂且不论这种写法效率高不高,假设即使是字符串应用,用于字符串结尾的空字符你写成'\0'不行吗?是你不知道'\0'的这种直观写法还是""[0]这种写法略显高深,是要让读代码的人为你感到赞叹?


你把常用于字符串的方法挪到了整型数组上来用,还假设了一下数组中不可以出现数字0,殊不知,0是整数中最常用的数字了吧,你这么一假设,这堆代码就成了废码了,这种代码只能在你故意没在里面写0才能用。


再来说说楼主的问题,众所周知其根本原因是数组在写操作中越界导致,写操作越界覆盖了栈中保存的返回地址等寄存器内容,导致函数返回时出栈操作恢复了错误的地址以致跑飞。


再来看看你给出的代码是否能解决楼主的问题,你只给出了读操作的算法,并且这个算法除了不应该用于字符串以外的其他类型我别的毛病我也挑不出来,但是,你为了解决楼主的问题,应该也是想把这个类似的思路用于写操作上,好,我来说说按你这种思路来防止写数组越界的可行性。
按你的思路就是写操作前,要判断一下数组内容是不是0(暂且不提这种低效率问题),如果是0就代表是数组的末尾,停止并结束写入。
假设有已知数组:
char arr[] = "helloworld";
此arr数组包含10个可见字符以及末尾的填充'\0',共11个字节。
现在开始第一次写操作,假设写入一个字符串"eric",好,没问题,为了能正确读出这个字符串,你需要把eric后面的'\0'也写入到arr中,那么现在arr中的内容就是:
// arr <=> "eric\0world" 期中末尾还包含一个隐式的'\0'
现在继续写操作,我要写入一个"eeworld"字符串,怎么样,出问题了,在写入过程中,写入下标为4时就有一个'\0',你以为到了数组的末尾,就不再写了。最后导致数组可用空间越来越小,成为不可用状态。


或许你没有以上的想法,那就算我瞎说了,不要太介意。


综上所述,我说你的代码
  1. int ar[3] = {1,2,3,NULL};
复制代码

没有意义也不为过


然而,你却并不是一无所知,你知道这个问题的正解就是老老实实的去判断写操作的下标不要超过某个常数或者sizeof(arr);,但是你却给出了一个不靠谱的答案,送给你四个字:”不厚道啊"!


我的言语可能比较刻薄,希望你不要介意,我希望我的回复可以给你带来帮助,毕竟论坛是技术交流的地方,不是叫嚣发泄的地方,不和谐之处请多多包涵!








点评

nice  详情 回复 发表于 2017-7-9 11:57
这事情都过去,现在跑过来再说 我早就说了没意义,揪着小辫子是不是很爽  详情 回复 发表于 2017-7-9 09:24

赞赏

2

查看全部赞赏

 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

沙发
 
试试在定义数组最后加个NULL

比如

int ar[3] = {1,2,3,NULL};

点评

我试了一下,编译提示有错误,我用的是IAR5.6的编译环境。 具体如下: 定义的数组是:unsigned char Password_Buffer[6]={0xff,0xff,0xff,0xff,0xff,0xff,NULL}; 提示的错误有两个:一个是提示数组中元素超过数  详情 回复 发表于 2017-7-7 11:51
这是错误的写法,没有意义。  详情 回复 发表于 2017-7-7 07:18
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

6040

帖子

205

TA的资源

版主

板凳
 
ywlzh 发表于 2017-7-6 23:16
试试在定义数组最后加个NULL

比如

int ar[3] = {1,2,3,NULL};

这是错误的写法,没有意义。

点评

在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论 楼主的问题是不定长度的数组怎么防止越界访问,我这只是提供了检测NULL就可以防止 [attachimg]310948[/attachimg][attachimg]310949[/attachimg  详情 回复 发表于 2017-7-7 09:29
 
 
 

回复

1792

帖子

0

TA的资源

五彩晶圆(初级)

4
 
上个月我刚出现了这个错误,MCU接的一个无线模块在某种情况会发出一些乱码,而且比正常数据要长,所以就溢出了。不知道有没有什么方法预防这种情况
 
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

5
 
lcofjp 发表于 2017-7-7 07:18
这是错误的写法,没有意义。

在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论

楼主的问题是不定长度的数组怎么防止越界访问,我这只是提供了检测NULL就可以防止


其中 (""[0]) 可以使用NULL也可以使用"\n"


点评

这种不靠谱的做法,我一眼能看得出来,还至于去编译一下吗? int ar[3] = {1,2,3,NULL}; 数组长度4写成3当你是笔误,这些都不细讨论了,我针对你后面的回复做下评论: 你基本功略显欠缺,即使你基本功不欠缺,  详情 回复 发表于 2017-7-7 19:56
不定长度,根本不会越界,int a[],里面都没写上数字,怎么可能越界。int ar[3] = {1,2,3,NULL};是无意义的,本来就是啊,你的解说并不能证明这个就是有意义的。  详情 回复 发表于 2017-7-7 10:23
麻烦解释一下 NULL 转成int是啥?如果运行过程中 执行ar[0] = NULL,那是不是变成空数组了呢?  详情 回复 发表于 2017-7-7 10:20
代码惊奇,前途不可限量  详情 回复 发表于 2017-7-7 10:17
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

307

帖子

4

TA的资源

一粒金砂(高级)

6
 
我倒是经常一部消息就用栈空间覆盖了堆空间,最后就导致程序出错(常常是莫名其妙的错误)。
现在430用着感觉很蛋汤,经常为了几个字节到处扣RAM空间,到处找哪里数组可以定义得小一点
 
 
 

回复

1403

帖子

1

TA的资源

纯净的硅(中级)

7
 
ywlzh 发表于 2017-7-7 09:29
在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论

楼主的问题是不定长度的数组怎么防 ...

代码惊奇,前途不可限量
 
个人签名HELLO_WATER
 
 

回复

1403

帖子

1

TA的资源

纯净的硅(中级)

8
 
ywlzh 发表于 2017-7-7 09:29
在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论

楼主的问题是不定长度的数组怎么防 ...

麻烦解释一下 NULL 转成int是啥?如果运行过程中 执行ar[0] = NULL,那是不是变成空数组了呢?

点评

你这属于没事找事 我不解释  详情 回复 发表于 2017-7-7 11:04
 
个人签名HELLO_WATER
 
 

回复

613

帖子

2

TA的资源

纯净的硅(初级)

9
 
本帖最后由 long521 于 2017-7-7 10:43 编辑
ywlzh 发表于 2017-7-7 09:29
在确定它是错误的写法前 你最好还是用你的编译器编译一下再下结论

楼主的问题是不定长度的数组怎么防 ...

过路党

点评

何必咬文嚼字 谁告诉你不定长的数组就不会越界! 这个程序中你把NULL去掉试试。 我为什么要在数组前后定义两个int数据? 扩展开来 说ar[3] = {1,2,3,NULL}没有意义,对是没有意义 但是ar[4] = {1,2,3,NULL}呢  详情 回复 发表于 2017-7-7 11:02
 
个人签名我是一头搞电子的猪,猪是一种好色的动物,猪八戒就是代表.       
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

10
 
本帖最后由 ywlzh 于 2017-7-7 11:07 编辑

何必咬文嚼字

谁告诉你不定长的数组就不会越界! 这个程序中你把NULL去掉试试。 我为什么要在数组前后定义两个int数据?

扩展开来 说ar[3] = {1,2,3,NULL}没有意义,对是没有意义,但没有错。
但是ar[4] = {1,2,3,NULL}呢?

if(ar == NULL) 会有警告信息,我就用了(""[0])来表示

点评

对于楼主这个问题来说,ar[4] 还是没有意义。。。  详情 回复 发表于 2017-7-7 11:19
if(ar == NULL) 编辑不了 就再回复下修改  详情 回复 发表于 2017-7-7 11:07
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

11
 
shinykongcn 发表于 2017-7-7 10:20
麻烦解释一下 NULL 转成int是啥?如果运行过程中 执行ar[0] = NULL,那是不是变成空数组了呢?

你这属于没事找事 我不解释

点评

出这么高大上的解决方案,不解释一下,没人看得懂怎么办?  详情 回复 发表于 2017-7-7 11:17
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

12
 
ywlzh 发表于 2017-7-7 11:02
何必咬文嚼字

谁告诉你不定长的数组就不会越界! 这个程序中你把NULL去掉试试。 我为什么要在数组前后 ...

if(ar == NULL) 编辑不了 就再回复下修改 用ar【i】 表示吧
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

1403

帖子

1

TA的资源

纯净的硅(中级)

13
 
ywlzh 发表于 2017-7-7 11:04
你这属于没事找事 我不解释

出这么高大上的解决方案,不解释一下,没人看得懂怎么办?

点评

不用深究 这个程序里面我故意没有用0,就是如果ar[0] = 0的情况,直接就break了。 至于你说的ar[0] = NULL 数组就会为空数组呢,答案肯定不是,即使你写了ar[0] = NULL,ar[0]最后结果是0 说那么多,为了防止  详情 回复 发表于 2017-7-7 11:44
 
个人签名HELLO_WATER
 
 

回复

1403

帖子

1

TA的资源

纯净的硅(中级)

14
 
ywlzh 发表于 2017-7-7 11:02
何必咬文嚼字

谁告诉你不定长的数组就不会越界! 这个程序中你把NULL去掉试试。 我为什么要在数组前后 ...

对于楼主这个问题来说,ar[4] 还是没有意义。。。
 
个人签名HELLO_WATER
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

15
 
本帖最后由 ywlzh 于 2017-7-7 11:49 编辑
shinykongcn 发表于 2017-7-7 11:17
出这么高大上的解决方案,不解释一下,没人看得懂怎么办?

不用深究 这个程序里面我故意没有用0,就是如果ar[0] = 0的情况,直接就break了。

至于你说的ar[0] = NULL 数组就会为空数组呢,答案肯定不是,即使你写了ar[0] = NULL,ar[0]最后结果是0

说那么多,为了防止数组越界,在访问之前计算数组的长度就行了。 一个sizeof不至于那么麻烦。
为什么用NULL呢?先看什么情况下,数组是没有0值的,字符串数组。
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

6366

帖子

4929

TA的资源

版主

16
 
ywlzh 发表于 2017-7-6 23:16
试试在定义数组最后加个NULL

比如

int ar[3] = {1,2,3,NULL};

我试了一下,编译提示有错误,我用的是IAR5.6的编译环境。
具体如下:
定义的数组是:unsigned char Password_Buffer[6]={0xff,0xff,0xff,0xff,0xff,0xff,NULL};

提示的错误有两个:一个是提示数组中元素超过数组长度,另一个是提示null未定义
Error[Pe146]: too many initializer values

Error[Pe020]: identifier "NULL" is undefined

点评

Pe146,要么用数组推断,也就是 a[]={1,2,3...}这样的写法,编译器静态推断长度。如果指定长度的话,静态检查报错是为质量负责,也应该报错。 Pe020,NULL是个宏,所以要#include  详情 回复 发表于 2017-7-7 23:15
我用的GCC 没错,只是有个警告 6不行可以用7呀  详情 回复 发表于 2017-7-7 11:53
 
 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

17
 
tiankai001 发表于 2017-7-7 11:51
我试了一下,编译提示有错误,我用的是IAR5.6的编译环境。
具体如下:
定义的数组是:unsigned char Pa ...

我用的GCC 没错,只是有个警告

6不行可以用7呀
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复

7452

帖子

2

TA的资源

五彩晶圆(高级)

19
 
tiankai001 发表于 2017-7-7 11:51
我试了一下,编译提示有错误,我用的是IAR5.6的编译环境。
具体如下:
定义的数组是:unsigned char Pa ...

Pe146,要么用数组推断,也就是 a[]={1,2,3...}这样的写法,编译器静态推断长度。如果指定长度的话,静态检查报错是为质量负责,也应该报错。
Pe020,NULL是个宏,所以要#include
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

1234

帖子

4

TA的资源

纯净的硅(高级)

20
 
lcofjp 发表于 2017-7-7 19:56
这种不靠谱的做法,我一眼能看得出来,还至于去编译一下吗?
int ar[3] = {1,2,3,NULL}; 数组长度4写成3 ...

这事情都过去,现在跑过来再说

我早就说了没意义,揪着小辫子是不是很爽

点评

算我多嘴,但是有一点要注意,不要写一堆烂代码还牛逼哄哄的,帮你指正代码是好事,你别好赖不分,就你写这代码拿出去都叫人笑掉大牙。本贴本人不再回复,以后我见你躲远远的。  详情 回复 发表于 2017-7-9 11:33
 
个人签名天地庄周马;江湖范蠡船。
个性签名还是放QQ号吧,2060347305,添加说明EEworld好友
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表