OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 354|回复: 11

都来看一下,关于空指针的引用和探讨,绝对会有启发

[复制链接]

1

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-8-27
在线时间
4 小时
发表于 2024-3-15 12:31:13 | 显示全部楼层 |阅读模式
对于一个求字符串长度的函数:StrLen
如果我们要求一个存在ram区的字符串u8 *str的长度,我们就需要u32 StrLen(u8* str);
但是如果我们要求一个存在flash区的字符串const u8 *str的长度,我们又需要u32 StrLen(const u8* str);
当然,如果是C++可以函数重载倒是可以,但是如果用C的话,这样就会非常麻烦

这个时候我们就可以这样处理
u32 MemStrLen(u32 str)
{
        u32 x;
        x = str;
        while( *(u8 *)x )x+=1;
        return(x - str);

}

然后我们再
#define StrLen(Mem) MemStrLen((u32)(Mem))
就可以用StrLen去求任意存储区域的字符串长度
试过了,编译运行都没有问题,不论是ram区或者是flash区的字符串长度都可以准确求出来
用这个方法还可以统一任意其他需要同时处理u8 和 const u8形参的函数

问题来了,我们需要一个对底层比较了解的大佬,来帮我们做一下鉴定,这样做是不是真的不会有问题
编译u8 *或者const u8*的数组,对他们取值的时候,用到的汇编指令都是ldr,看上去好像一切都没有问题

但是汇编我是真的不了解,还希望有大佬来帮忙判定一下
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2023-12-6
在线时间
26 小时
发表于 2024-3-16 11:33:43 | 显示全部楼层
你直接函数内定义一个指针去指向传进来的地址不就行了, char * p = (char *)str。不管传进去的是uint8_t const * 还是 uint8_t * 还是uint8_t * const还是uint8_t const * const都可以。
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-8-27
在线时间
4 小时
 楼主| 发表于 2024-3-16 13:58:20 | 显示全部楼层
JiangYoo 发表于 2024-3-16 11:33
你直接函数内定义一个指针去指向传进来的地址不就行了, char * p = (char *)str。不管传进去的是uint8_t c ...

你没看懂这个帖子的真正问题所在

我们为什么要区分u8 *pt和const u8 *pt?
如果在桌面系统这样近似于无限资源的环境下,我认为做这种区分的意义不大,都是存在内存里面,只是逻辑上区分而已,用不用const 没有太本质的区别
但是在有限资源的单片机,这种区分就很重要了,比如建菜单,就要全部建在flash里面,全部用const

存储区的不同,很可能带来汇编指令的不同,汇编指令对于在ram区的取值或者取址很可能与在flash区不一样

这里面重点不在于while( *(u8 *)x )x+=1;这个操作,而在于u32 str形参不知道你是来自于ram还是flash区,这样的话全部都 *(u8 *)x这样处理就有可能出错,正常情况,在ram区的数据可以 *(u8 *)x这样操作,来自于flash区的数据应该是*(const u8 *)x这样操作

我对stm32的汇编是完全不熟,所以才发帖子出来讨论
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2023-12-6
在线时间
26 小时
发表于 2024-3-16 14:42:21 | 显示全部楼层
苏嫒道范砝 发表于 2024-3-16 13:58
你没看懂这个帖子的真正问题所在

我们为什么要区分u8 *pt和const u8 *pt?

1. 你先去试试用uint32_t*不加const看能不能访问flash数据;
2. 对于获取字符串长度,正常写库的人都是用const限定该指针指向的数据不能修改,不会因为是访问RAM内存的数据而特地去使用不加const的;
3. 你没有理解const uint8_t * 指针的意义,加const是限定该指针访问的数据不能修改,不是因为它数据本身可不可以修改,跟raw和flash没有任何关系。
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2023-12-6
在线时间
26 小时
发表于 2024-3-16 14:42:48 | 显示全部楼层
JiangYoo 发表于 2024-3-16 14:42
1. 你先去试试用uint32_t*不加const看能不能访问flash数据;
2. 对于获取字符串长度,正常写库的人都是 ...

第一点访问改成读取
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
12
金钱
12
注册时间
2023-8-27
在线时间
4 小时
 楼主| 发表于 2024-3-16 14:59:53 | 显示全部楼层
JiangYoo 发表于 2024-3-16 14:42
1. 你先去试试用uint32_t*不加const看能不能访问flash数据;
2. 对于获取字符串长度,正常写库的人都是 ...

你可能没有用汇编写过代码,对汇编的认识不够,而且对单片机的存储结构认识的也不够
而且你相信我,这个世界没有人比我更了解指针
在我眼里,已经完全没有指针类型这个概念了,我操作指针完全不局限指针类型,在我的眼里,指针就是四个字节,它的分别只有存储区域的区别,还有就是你从这个地址开始到底取走了几个字节
如果是单片机系统,const描述的数据,真的是不能改,因为它写到FLASH里面了,但是桌面系统,你通过其他指针强行变更const变量,因为它不过是在ram里面逻辑上设定一个值说它不能修改,只是假装不能修改而已,实际上是可以改的
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
125
金钱
125
注册时间
2023-12-6
在线时间
26 小时
发表于 2024-3-16 15:03:06 | 显示全部楼层
苏嫒道范砝 发表于 2024-3-16 14:59
你可能没有用汇编写过代码,对汇编的认识不够,而且对单片机的存储结构认识的也不够
而且你相信我,这个世 ...

👍
回复 支持 反对

使用道具 举报

2

主题

23

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2019-12-2
在线时间
18 小时
发表于 2024-3-18 20:47:18 | 显示全部楼层
苏嫒道范砝 发表于 2024-3-16 14:59
你可能没有用汇编写过代码,对汇编的认识不够,而且对单片机的存储结构认识的也不够
而且你相信我,这个世 ...

兄弟,那位大兄弟说的是对的,要听的进去别人的指导。
你这点东西还不涉及到汇编。先认真学习下const的用法:函数形参加const,只是说此参数在函数内只读,只给编译时判断用法是否有误,不涉及到放在flash,还是在ram。
回复 支持 反对

使用道具 举报

7

主题

482

帖子

0

精华

高级会员

Rank: 4

积分
745
金钱
745
注册时间
2021-4-15
在线时间
302 小时
发表于 2024-3-19 10:08:11 | 显示全部楼层
回复 支持 反对

使用道具 举报

28

主题

354

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2021-2-4
在线时间
137 小时
发表于 2024-3-19 13:35:19 | 显示全部楼层
苏嫒道范砝 发表于 2024-3-16 14:59
你可能没有用汇编写过代码,对汇编的认识不够,而且对单片机的存储结构认识的也不够
而且你相信我,这个世 ...

你先学一下 StrLen 这个函数吧
size_t strlen(const char *str)
这是函数的声明
看你这个函数,指针的事情以后再说,数据类型你都没弄清楚
回复 支持 反对

使用道具 举报

28

主题

354

帖子

0

精华

高级会员

Rank: 4

积分
994
金钱
994
注册时间
2021-2-4
在线时间
137 小时
发表于 2024-3-19 13:47:48 | 显示全部楼层
对于一个求字符串长度的函数:StrLen
如果我们要求一个存在ram区的字符串u8 *str的长度,指针的长度等于系统位数
但是如果我们要求一个存在flash区的字符串const u8 *str的长度,指针的长度等于系统位数

如果我们要求一个存在ram区的字符串u8 str的长度, 我们就需要
  1. strlen((const char*)str);
复制代码

但是如果我们要求一个存在flash区的字符串u8 str的长度, 我们还是只需要
  1. strlen((const char*)str);
复制代码


所以没有什么麻烦




回复 支持 反对

使用道具 举报

3

主题

1906

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4095
金钱
4095
注册时间
2018-8-14
在线时间
694 小时
发表于 2024-3-20 04:02:13 | 显示全部楼层
u32 StrLen(const u8* str);
它的意思是 str是个常量,不可改变, 而不是你所理解的str是指向常量的指针
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-6-11 08:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表