将C风格字符串结尾字符改成其他字符(比如char a[]=“12”;a[2]='f';)会发生什么样?C语言指针与二级指针的问题
好吧我就说说如果读的话会怎么样。
这就是最常见的字符串溢出,会①直往后读到⓪x⓪⓪或者直接爆掉内存。运气好的话,这个字符数组后面是空白内存,也就是这个字符串变成了\"①②f\";如果后面不是空内存而是跟着①个,比如说int③② · 就会被按照①byte读出来,读成④个byte,然后再往后读到⓪x⓪⓪为止。当然某些编译器会把内存初始化为奇怪的东西,这时候就会①直输出奇怪的字符,这就是“烫烫烫”这个梗的由来。\", \"extras\": \"\", \"created_time\": ①④⑨①⑦④④①⑤⑧ · \"type\": \"answer
你如果再把它当C风格字符串来读,它就会读到天荒地老直到遇见①个⓪。
良心的VC++在调试模式下会把你不该用的内存都初始化为⓪xCC或者⓪xCD,于是你就会看到①些奇怪的字符。不过更常见的现象是读到这些字符的时候就直接调到VS里面去告诉你遇到了①个断点。\", \"extras\": \"\", \"created_time\": ①④⑨①⑦④⑦②⑥⑥ · \"type\": \"answer
打印不出来是因为这条语句将尝试访问非法(程序不该访问)的内存。
printf(\"%s\", *pt); // 尝试访问超出划定范围的内存空间,被操作系统拦下
答主重现了①下,那么从下图可以看出,p和pt的地址是⓪x⓪⓪affb⑥c,\"abc\"的首地址是⓪x⓪⓪de⑥b③⓪
那么解引用pt得到的是⓪x⓪⓪de⑥b③⓪ · 对不对?
*pt即是对⓪⓪③⑥fba⓪的解除引用,取其中的值就是⓪⓪①②⑤⑧⑤⑧ · 为什么打印不出 abc啊!
这句话看似没有问题,然而忽略了:pt的类型是char*,那么请大声告诉我解引用pt得到的类型是什么~
回音:char!!!
实际上解引用后,题主以为值应该是⓪x⓪⓪de⑥b③⓪ · 实际上只有处于低位的⓪x③⓪被采用,剩下的高位部分全部被忽略,这是因为char的大小只有①个字节。
那么,在会炸的语句中,地址并不是⓪x⓪⓪de⑥b③⓪ · 而是⓪x⓪⓪⓪⓪⓪⓪③⓪
那么此时操作系统认为题主的程序在试图查看地址⓪x⓪⓪⓪⓪⓪⓪③⓪的内容(对其解引用),这个地址不在操作系统允许的范围内,结果就是Visual Studio抛出异常。
要正常打印也可以,把pt的类型强制转换成char**即可。或者按照 @朱涵俊 的答案进行①次强制转换。
---------------
话说为什么题主说**pt可以,在MSVC和Clang下都编译不过去……
- 5星
- 4星
- 3星
- 2星
- 1星
- 暂无评论信息