一个const char*形参引发的“血案”

文章目录

问题

c/c++大神请出门右转。
话不多说,先看如下代码,可以发现传入的第一个形参是const char *pFile它是一个指向char类型内容的指针变量。表示指向的内容不会发生改变,但是他自己本身的地址是可以改变的。而且作为形参传入时,已经默认做了一次指针拷贝,传入此函数的pFile已经和传入时的pFile无关了,函数内部做修改并不会改变外部的地址。
在使用内存映射读取文件时,调用该函数却忽略了这一点,导致在函数外疯狂计算pFile的位置,带来各种溢出。

inline void parseSPTmmf (const char *pFile, const std::uint32_t &pts_num, const pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud, const int &pt_length)
{
	int size_float3 = sizeof(float) * 3;
	float *data = new float[3];
	pcl::PointXYZ pt;
	for (int singlepoint = 0; singlepoint < pts_num; ++singlepoint)
	{
		memcpy(data, pFile, size_float3);
		pFile += pt_length;
		pt.x = data[0];
		pt.y = data[1];
		pt.z = data[2];
		cloud->push_back(pt);
	}
	delete[]data;
}

本质

是对const char * & char *等指针不熟悉导致的。看来候老师说的对,莫在浮沙筑高台,基础不牢地动山摇啊!!!
这里贴出其他博主的一个解释。ref1
c/c++中一个简单的声明有两部分组成: specifiersdeclarator

  • declarator 就是声明的名字以及包裹在他外面的其他一大堆符号,例如 &, &&, *, *const
  • 其中 specifiers 分成两种。
    • 一种是 type specifiers ,表明整个 declarator 返回什么类型。例如 int , unsigned , const 。这些 type specifiers 可以任意调换顺序。例如写 unsigned int , int unsigned , int const , const int 都是一样的。
    • 还有一种是 non-type specifiers ,并不说明类型,而是表示声明的名字的属性。例如 inline , static 这些,也可以任意调换顺序。
declarator => * cv(optional) declarator

这里的 cv 是修饰右侧的 declarator 的。例如 *const volatile p 这个 cv 修饰的是 p 。这个指针声明表示 * 后面的 cv(optional) declarator 是指向 type specifiers 的指针。
所以, const char *p 表示的是 *p ( declarator )的返回类型是 const char 。而 *p 表示 p 是指向 const char ( type specifiers )的指针。因为 type specifiers 可以任意调换顺序,所以 char const *pconst char *p 一样。而 char *const p 则表示 type specifiers 是 char , const p 是指向 char 的指针。

  • constexpr 显然是 non-type specifier ,表明名字的属性,不表示类型。 constexpr 不可以放在 declarator 一侧,指针只可以被 cv 修饰。 constexpr int *p 中的 constexpr 和 static 或者 inline 一样,表示 p 的属性。而因为 constexpr 蕴含了 const ,所以 p 是 const 指针,指向 int 。

Reference

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值