http://stackoverflow.com/questions/3228664/why-am-i-able-to-change-the-contents-of-const-char-ptr

I passed a pointer ptr to a function whose prototype takes it as const.

foo( const char  *str );

Which according to my understanding means that it will not be able to change the contents of ptrpassed. Like in the case of foo( const int i ). If foo() tries to chnage the value of i, compiler gives error. 
But here I see that it can change the contents of ptr easily. 
Please have a look at the following code

foo( const char  *str )
{
strcpy( str, "ABC" ) ;
printf( "%s(): %s\n" , __func__ , str ) ;
} main()
{
char ptr[ ] = "Its just to fill the space" ;
printf( "%s(): %s\n" , __func__ , ptr ) ;
foo( const ptr ) ;
printf( "%s(): %s\n" , __func__ , ptr ) ;
return;
}

On compilation, I only get a warning, no error:

warning: passing argument 1 of ‘strcpy’ discards qualifiers from pointer target type

and when I run it, I get an output instead of Segmentation Fault

main(): Its just to fill the space
foo(): ABC
main(): ABC

Now, my questions is
1- What does const char *str in prototype actually means? 
Does this mean that function cannot change the contents of str? If that is so then how come the above program changes the value?
2- How can I make sure that the contents of the pointer I have passed will not be changed?

From "contents of the pointer" in the above stated question, I mean "contents of the memory pointed at by the pointer", not "address contained in the pointer".

Edit

Most replies say that this is because of strcpy and C implicit type conversion. But now I tried this

foo( const char  *str )
{
str = "Tim" ;
// strcpy( str, "ABC" ) ;
printf( "%s(): %s\n" , __func__ , str ) ;
}

This time the output is, with no warning from compiler

main(): Its just to fill the space
foo(): Tim
main(): Its just to fill the space

So apparently, memory pointed to by str is changed to the memory location containing "Tim" while its in foo(). Although I didn't use strcpy() this time.
Is not const supposed to stop this? or my understanding is wrong?

To me it seems that even with const, I can change the memory reference and the contents of memory reference too. Then what is the use?

Can you give me an example where complier will give me error that I am trying to change a const pointer?

Thanks to all of you for your time and effort.

Your understanding is correct, const char* is a contract that means you can't change memory through this particular pointer.

The problem is that C is very lax with type conversions. strcpy takes a pointer to non-const char, and it is implicitly converted from const char* to char* (as compiler helpfully tells you). You could as easily pass an integer instead of pointer. As a result, your function can't change content pointed by ptr, but strcpy can, because it sees a non-const pointer. You don't get a crash, because in your case, the pointer points to an actual buffer of sufficient size, not a read-only string literal.

To avoid this, look for compiler warnings, or compile, for example, with -Wall -Werror (if you are using gcc).

This behaviour is specific to C. C++, for example, does not allow that, and requires an explicit cast (C-style cast or a const_cast) to strip const qualifier, as you would reasonably expect.

Answer to the extended question

You are assigning a string literal into a non-const char, which, unfortunately, is legal in C and even C++! It is implicitly converted to char*, even though writing through this pointer will now result in undefined behaviour. It is a deprecated feature, and only C++0x so far does not allow this to happen.

With that said, In order to stop changing the pointer itself, you have to declare it as const pointer to char (char *const). Or, if you want to make it that both the contents pointed by it and the pointer itself don't change, use a const pointer to const char (const char * const).

Examples:

void foo (
char *a,
const char *b,
char *const c,
const char *const d)
{
char buf[10];
a = buf; /* OK, changing the pointer */
*a = 'a'; /* OK, changing contents pointed by pointer */ b = buf; /* OK, changing the pointer */
*b = 'b'; /* error, changing contents pointed by pointer */ c = buf; /* error, changing pointer */
*c = 'c'; /* OK, changing contents pointed by pointer */ d = buf; /* error, changing pointer */
*d = 'd'; /* error, changing contents pointed by pointer */
}

For all error lines GCC gives me "error: assignment of read-only location".

Why am I able to change the contents of const char *ptr?的更多相关文章

  1. Redis中的数据结构

    1. 底层数据结构, 与Redis Value Type之间的关系 对于Redis的使用者来说, Redis作为Key-Value型的内存数据库, 其Value有多种类型. String Hash L ...

  2. unity导出工程导入到iOS原生工程中详细步骤

    一直想抽空整理一下unity原生工程导入iOS原生工程中的详细步骤.做iOS+vuforia+unity开发这么长时间了.从最初的小小白到现在的小白.中间趟过了好多的坑.也有一些的小小收货.做一个喜欢 ...

  3. Array类

    class Array Arrays are ordered, integer-indexed collections of any object. Array indexing starts at ...

  4. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

  5. 基于Httpfs访问HDFS的C++实现

    Httpfs是hadoop2.x中hdfs项目的内置应用,基于tomcat和jesery,对外提供完备HDFS操作的RESTful接口,无需安装客户端,可方便实现数据交互,如从windows访问存储在 ...

  6. libcurl的封装,支持同步异步请求,支持多线程下载,支持https

    最近在做一个项目,需要用到http get post等 需求分析需要做到同步和异步,异步请求的返回以可选的回调通知的方式进行. 本人以Linux为例,一步一步的来实现. 配置并且编译libcurl我以 ...

  7. leveldb 学习记录(四)Log文件

    前文记录 leveldb 学习记录(一) skiplistleveldb 学习记录(二) Sliceleveldb 学习记录(三) MemTable 与 Immutable Memtablelevel ...

  8. 5、QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

  9. 安卓加固之so文件加固

    一.前言 最近在学习安卓加固方面的知识,看到了jiangwei212的博客,其中有对so文件加固的两篇文章通过节加密函数和通过hash段找到函数地址直接加密函数,感觉写的特别好,然后自己动手实践探索s ...

随机推荐

  1. iOS数据持久化-SQLite数据库使用详解

    使用SQLite数据库 创建数据库 创建数据库过程需要3个步骤: 1.使用sqlite3_open函数打开数据库: 2.使用sqlite3_exec函数执行Create Table语句,创建数据库表: ...

  2. Codevs 1078 ==Poj 1258 Agri-Net

      Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 53270   Accepted: 22140 Description D ...

  3. Codevs 2894 Txx考试

    时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题目描述 Description Txx是一个成绩很差的人,考试便成了他的噩梦.于是他常在考试时睡觉以打发时间.今天 ...

  4. 驾照理论模拟考试系统Android源码下载

    ‍‍‍驾照理论模拟考试系统Android源码下载 <ignore_js_op> 9.png (55.77 KB, 下载次数: 0) <ignore_js_op> 10.png ...

  5. 2_1我的第一个应用hello world[wp8特色开发与编程技巧]

    2_1hello world -5min 大家好,我是徐文康,在上一个视频当中我们已经讲了,如何根据自己电脑系统去下载相应的SDK. 你可能花了很多时间去安装以及配置好了这个开发环境,如果还没有配置好 ...

  6. unity 3消 游戏

    3消游戏跟着智能手机流行到现在已经有很长一段时间,unity实现的3消 https://github.com/textcube/match3action 截图如下: 在阅读源码的时候不难发现,Game ...

  7. SQL2008、SQL2013 执行Transact-SQL 语句或者批处理时发生了异常。错误5120

    附加数据库的时候遇到问题,问题描述如下: 附加数据库 对于 服务器"服务器名"失败.(Microsoft.SqlServer.Smo) 执行Transact-SQL 语句或者批处理 ...

  8. Linux下解决apache 报 403 forbidden 错

    三步搞定: 1. 打开终端 2. 输入 chcon -R -t httpd_sys_content_t /var/www/html # 后面的/var/www/html是网站的默认目录,可以根据自己的 ...

  9. ◆linux分区的加密与自动解密◆——Super孟再创辉煌

    首先制作分区的加密挂载: 分区的自动解密:

  10. Java 多线程的基本概念

    一.线程介绍 多线程同时运行时,单CPU系统实际上是分给每个线程固定的时间片,用这种方式使得线程“看起来像是并行的”.在多CPU系统中,每个CPU可以单独运行一个线程,实现真正意义上的并行,但是如果线 ...