你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

问一个C语言上的问题

[复制链接]
NapoleonWang 提问时间:2017-4-11 11:15 /
悬赏5ST金币已解决
调试程序过程中,遇到了一个问题。如下:
#define  DEFAULT_SE          "000000 "   //有7个字符



char SerialNum[7];  //定义一个数组


strcpy( SerialNum , DEFAULT_SE);  //复制内存中的数据


i =strlen(DEFAULT_SE);
j=strlen(SerialNum);


结果打印出来的:
i=7
j>7(j是一个大于7的数)


我的疑问不确定,大家帮我分析下:
1、宏定义DEFAULT_SE虽然是7个字符,但是后面编译器自动加了一个\0 吗?,那实际上是不是有8个字符长度?
2、由于SerialNum 的定义只有七个字节宽度,导致strcpy(SerialNum, DEFAULT_SE)没有将\0复制过去,也就是SerialNum结尾没有\0,导致计算得j>7呢?


另外,看了一下百度百科对C语言中strcpy的介绍:
C语言标准库函数strcpy,把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间
也就是说strcpy这个函数是把最后的\0复制过去的,根本原因是我这个地方定义数组内存不够导致的,是这样的吗?


还请各位老师指教。谢谢。

最佳答案

查看完整内容

楼主只说有7个字符(没说7个0),这个没毛病。 潜在的毛病是: 1.strcpy会通过判断‘\0’来遍历DEFUALT_SE,然后把所有的有效字符都复制到SerialNum里面,你没有在这里死机是因为:刚好第7个字符是‘\0’也就不再复制了,虽然这里没死机,但是这是你碰上了,而不是你的业务能力好(反而明显的暴露了你的水平)。这种写法虽然没死机但实际是错误的(如下述)! 2.一般,定义一个字符串,然后使用C库里面的字符串处理函数,比如str ...
收藏 评论14 发布时间:2017-4-11 11:15

举报

14个回答
moyanming2013 回答时间:2017-4-11 11:15:26
本帖最后由 moyanming2013 于 2017-4-11 12:30 编辑
MrJiu 发表于 2017-4-11 11:43
首先,你要去小学进修一下下!!!"000000 "->这只有6个0,不是7个;
其次,字符串很显然是会在后面加\0的 ...

QQ截图20170411121411.jpg
楼主只说有7个字符(没说7个0),这个没毛病。
潜在的毛病是:
1.strcpy会通过判断‘\0’来遍历DEFUALT_SE,然后把所有的有效字符都复制到SerialNum里面,你没有在这里死机是因为:刚好第7个字符是‘\0’也就不再复制了,虽然这里没死机,但是这是你碰上了,而不是你的业务能力好(反而明显的暴露了你的水平)。这种写法虽然没死机但实际是错误的(如下述)!
2.一般,定义一个字符串,然后使用C库里面的字符串处理函数,比如strlen、strcpy等等,都需要确保最后必须有个‘\0’,C库函数都是用‘\0’来判断遍历的结束的,所以,对于SerialNum来说执行完strcpy后,它里面没有‘\0’,导致的结果是后续对SerialNum用C库函数都会有死机的风险,而且风险巨大。编译器对显示字符串都会在其最后自动添加一个‘\0’。
3.上述C库是老库,你可以用诸如strncpy等带有‘n’的保险的c库函数,在一些时候它可以给你“我是对的”的假象,其实你是碰上了,但实际是错误的。再者,你可以自己写一些类似的函数而不用关注‘\0’,但必须指定真实的长度,比如针对SerialNum,真实长度是7,必须时刻跟着长度!这个时候,往往把它做成一个结构体,一个数组成员str,一个实际长度成员strLen。此时就可以不用特殊的‘\0’了(节省了1个字节),因为我们自己处理。

MrJiu 回答时间:2017-4-11 11:43:26
首先,你要去小学进修一下下!!!"000000 "->这只有6个0,不是7个;
其次,字符串很显然是会在后面加\0的,否则就不叫字符串了;
最后,至于你说的j打印出来的值是大于7的...我觉得不太可能,因为SerialNum的内存是够存储的!!!当然,除非你把"000000 "6个0变成7个0,这样SerialNum就不够存储了!!但是,strcpy和strlen都是以检测\0作为检测结束符,所以,有可能数组溢出,进而导致跑飞!!!!
NapoleonWang 回答时间:2017-4-11 13:10:16
MrJiu 发表于 2017-4-11 11:43
首先,你要去小学进修一下下!!!"000000 "->这只有6个0,不是7个;
其次,字符串很显然是会在后面加\0的 ...

首先确实是六个0,后面加个空格。一看到你说的前一句,下面的就懒得看了。还是看看楼下的兄弟解答吧。;olo
NapoleonWang 回答时间:2017-4-11 13:29:25
  bu neng da zi,  bu neng  hui fu .shen me qing kuang .  wo xiang hui lou shang  de .
NapoleonWang 回答时间:2017-4-11 13:46:03
moyanming2013 发表于 2017-4-11 12:26
楼主只说有7个字符(没说7个0),这个没毛病。
潜在的毛病是:
1.strcpy会通过判断‘\0’来遍历DEFUALT_S ...

wei  shen  me  bu  neng  da zi ......
MrJiu 回答时间:2017-4-11 13:48:53
moyanming2013 发表于 2017-4-11 12:26
楼主只说有7个字符(没说7个0),这个没毛病。
潜在的毛病是:
1.strcpy会通过判断‘\0’来遍历DEFUALT_S ...

注意楼主的下面言论,第7个不是指\0的,然后楼主补充了一下,后面有个空格...说实话这个空格完全就是考虑人的眼神啊,
MrJiu 回答时间:2017-4-11 13:51:59
NapoleonWang 发表于 2017-4-11 13:10
首先确实是六个0,后面加个空格。一看到你说的前一句,下面的就懒得看了。还是看看楼下的兄弟解答吧。;ol ...

首先,你这个问题完全就是误导人啊!!!!鬼会注意别人的空格!!!
其次,我下面的解释恰好是完全正确的,注意我说了这么一句话:至于你说的j打印出来的值是大于7的...我觉得不太可能,这是基于我没有注意到空格的前提得出的结论....如果是由空格,那j的值就是一个看情况,未知的值,因为完全取决于这个只指针自加的时候,什么时候指到的值是\0就结束!!!
moyanming2013 回答时间:2017-4-11 15:12:29
MrJiu 发表于 2017-4-11 13:48
注意楼主的下面言论,第7个不是指\0的,然后楼主补充了一下,后面有个空格...说实话这个空格完全就是考虑 ...

我当然看到有个空格啦,我看你的回复你是没看到这个空格。
还是我说的,7个字符没错啊:6个0+1个空格=7个字符,你说楼主(红框部分):
QQ截图20170411150422.jpg
楼主没说有7个0啊!再说了,楼主说7个字符也没错啊(是你少看了1个空格)。要我说不要在眼神上下文章,这个眼神完全不是重点,重点是没看清还胡说。
哎~~再再说了,你作为版主怎么能这么说楼主呢,要是大家什么都会,还要论坛干什么,还要工作干什么,去大街上等风把钱刮过来就行了。不能以为自己是版主就开始卖弄,更不能侮辱别人!子曰“三人行,必有我师焉”。
请问你只发过3个主题帖,怎么当上的版主?
QQ截图20170411150620.jpg
moyanming2013 回答时间:2017-4-11 15:34:59
我3楼(https://www.stmcu.org.cn/module/ ... amp;fromuid=3089512)讲了那么多理论还没看明白啊,我还是针对你的问题通俗点回答你吧:
1.编译器会自动给显示字符串加1个字符‘\0’,但实际上字符长度是7。
注意:编译器自动加个字符,也会自动管理这里面的内存分配。这和字符数组不同,字符数组的大小是确定的,内存分配也是确定的,故要给出1个空余字节来存放‘\0’,否则参考我回复的3楼里面的第3条。
2.strcpy什么都不知道,只知道复制内存,遇到‘\0’就停止。同时为了保证C字符串的完整性,会把这个‘\0’添加到(或复制到)目的地址。此时,因为SerialNum的大小是7,所以往第7个下标写‘\0’时会死机,但这里没死机,没死机是个意外,死机才是正常的,我分析可能是由于字符对齐、编译器优化等等才会没死机,致使第7个内存位置是可读写的位置。因为SerialNum的大小是7,此时该数组里面没有‘\0’,当使用C库函数strlen(SerialNum)时,至少在前7个字节中找不到结束标识‘\0’,故j>=7,没死机你很万幸,但完全是错误的!因为strlen会继续找下去直到碰到‘\0’才停止,你想想会如何呢?会碰到不可读的内存,此时会出现硬件错误!

点评

解释正确,这个确实是初学者容易犯的错误!  发表于 2017-4-14 07:05
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版