const这样用不会有问题吧?

mocom 2010-07-25 07:49:43
在Apache源码中看到const的一个用法,简化下就是这样的:

void substr(const char *str, int pos, int len, const char **result) {
char *ret = (char *)malloc((len + 1) * sizeof(char));
memmove(ret, str + pos, len);
ret[len] = 0;
*result = ret;
}

void free2(const char *str) {
free((void *)str);
}

//应用:
const char *str = "Hello World";
const char *buf;
substr(str, 0, strlen(str), &buf);
free(buf);


内存分配和释放,他都用const,这样也可以么?
...全文
209 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mymtom 2010-07-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mocom 的回复:]

奇怪了,声明是const,可是经过substr转换后就可以更改数据;

例如:

const char *buf = "Hello";
char *p = (char *)buf;
p[0] = 'A';
//这样无法更改数据,p = "Hello"
substr("Hello", 0, 5, &buf);
p = (char *)buf;
p[0] = 'A';
……
[/Quote]
void substr(const char *str, int pos, int len, const char **result)
const 的意思是
1. 如果你要实现这个函数,你不能修改str和 result
2. 如果你要调用这个函数,你得到一种保证:此函数不会修改str和result指向的内容。
换个说,你可以这样调用substr

substr("String", ...)

但是如果const char *str变成 char *str
substr("String", ...)将是非法的。

zhangweiit 2010-07-25
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 mocom 的回复:]

又测试了下:

char *str = "Hello";
char *p = str;
p[0] = 'A';
printf("%s\r\n", p); //还是输出Hello

难道跟const无关么?只要是程序自身分配的内存就无法更改?
[/Quote]

楼主,我不信你这段代码能运行得起来

p[0] = 'A';这里要修改const char []的内容,会有运行时错误的
zhangweiit 2010-07-25
  • 打赏
  • 举报
回复
1,当函数形参是const的时候,可以传const的实参,也可以传非const的
2,但函数开参是非const的时候,就不能传const的实参了
3,free只是重新把这一段内存标记为可用,并没有做其它清空的事
mocom 2010-07-25
  • 打赏
  • 举报
回复
又测试了下:

char *str = "Hello";
char *p = str;
p[0] = 'A';
printf("%s\r\n", p); //还是输出Hello

难道跟const无关么?只要是程序自身分配的内存就无法更改?
pengzhixi 2010-07-25
  • 打赏
  • 举报
回复
而且 free只是释放内存,并不修改内存里面的内容。
Johnson_Jiang327 2010-07-25
  • 打赏
  • 举报
回复
const char *p,其中const修饰的是char *这个指针类型,表示该指针是常量指针,指针本身的值不能修改,但是指针指向的内存空间的值可以修改;
char * const p,const修饰的是变量p,表示该指针指向的是指针常量,指针值可以改变,指针指向的值不能改变。
const char * const p则兼有前两种的意思。
pengzhixi 2010-07-25
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 mocom 的回复:]
奇怪了,声明是const,可是经过substr转换后就可以更改数据;

例如:

const char *buf = "Hello";
char *p = (char *)buf;
p[0] = 'A';
//这样无法更改数据,p = "Hello"
substr("Hello", 0, 5, &buf);
p = (char *)buf;
p[0] = 'A';
……
[/Quote]

因为在substr函数里面重新malloc了内存,而buf指向了这段内存。
vannius 2010-07-25
  • 打赏
  • 举报
回复
应该没问题,他只是修饰的指针吧
localxiao 2010-07-25
  • 打赏
  • 举报
回复
char *p;

const char *buf;

前者没有用const修饰声明,自然可以改
cattycat 2010-07-25
  • 打赏
  • 举报
回复
参数是const的,防止被修改的可能。
free的时候会自己转换,这么没问题。
mocom 2010-07-25
  • 打赏
  • 举报
回复
奇怪了,声明是const,可是经过substr转换后就可以更改数据;

例如:

const char *buf = "Hello";
char *p = (char *)buf;
p[0] = 'A';
//这样无法更改数据,p = "Hello"
substr("Hello", 0, 5, &buf);
p = (char *)buf;
p[0] = 'A';
//这样就可以更改数据了,p = "Aello"
Proteas 2010-07-25
  • 打赏
  • 举报
回复

void free2(const char *str) {
free((void *)str);//强转成非const的了
}


我对于申请的部分,
const的应用没觉得有什么,
对参数进行最大的限制,
我也觉得是这样:如果你的库不能提供某种用法或者不能那样使用,
要用语言特性去限制用户不要那样用,而不是告诉用户不要那样用。
释放部分是为了去掉警告。
localxiao 2010-07-25
  • 打赏
  • 举报
回复
应该是优化以后,const会常量替换

看不到变量了

你改不改内存,他都不从内存里面读,有什么关系呢?
你可以试试开汇编看看,不同的优化程度应该是不同的
mocom 2010-07-25
  • 打赏
  • 举报
回复
嗯,基本明确了,总结一下看理解的对不对

const是给编译器看的,编译程序时,如果声明某const参数,更改这个参数则会抛出错误,const只是个限定,提示编译器该变量不能变动,但其被强制转换类型后,实际还是根据内存地址来确定是否可以变动,也就是形参和实参的分别

不管是否const,指针指向程序内部分配的内存地址则无法更改值,例如:
const char *buf = "***"; //or
char *buf = "***";
而指针指向动态分配的内存(也就是数组)则能更改值,例如:
const char *buf = malloc(10); //相当于const char buf[10];
char *p = (char *)buf;
*p++ = 'A';
*p++ = 0;//但是不知道这样更改值会不会造成内存泄露这些不可预料的错误?

还有10楼朋友的疑问,那段程序可以编译和运行,编译环境:MinGW GCC 4.4,编译选项是抛出所有警告并且优化级别3:-Wall -O3,编译不会抛出警告,程序运行也不会崩溃,但就是无法更改值

69,336

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧