一个小函数内存的bug,如何理解!

wbuzhou 2014-07-23 11:05:21
#include<string.h>
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>

void LowerString()
{
char *p = "WanG";
while ( *p != 0 )
{
printf("p = %x *p = %c \n",p,*p);
if ( ( 'A' <= *p ) && ( *p <= 'Z' ) )
{
*p = tolower('D');
printf("*p = %c\n",*p);
}
p++;
}
}


main()
{
LowerString();
}
...全文
379 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Iflyinsky2013 2014-07-27
  • 打赏
  • 举报
回复
额。。。说白了:指针p中的内存地址就是指向这个字符串的第一个字符,你觉得一个定义了的字符串(系统已经为这个字符串分配好了内存),他的地址是你可以随便改变的吗???
鼻涕虫de皮皮 2014-07-25
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
#pragma comment(linker,"/SECTION:.rdata,RW")
//加这句可以让常量区可写,后果自负!
还是不可以写啊,linux下测试的
鼻涕虫de皮皮 2014-07-25
  • 打赏
  • 举报
回复
引用 3 楼 liuxiaohailxh8888 的回复:
改写常量需要用memset
我居然信了,还好测试了一下
tixisong 2014-07-25
  • 打赏
  • 举报
回复
引用 4 楼 virtualxmars 的回复:
这一句:

char *p = "WanG";
因为"WanG"对编译器来说实际上是一个常量,也就是不允许变化的量,所以将其赋值给char *p是不对的,因为 char * 实际上指出p是可以被修改的。而"WanG"其实会被放在不可编辑的全局符号表位置。那么你后面的修改就是非法的了。 解决办法是:

    char name[] = "WanG";
    char *p = name;
由于引入了数组,所以"WanG"会定义在函数的堆中,这样,它就变成了可被修改的内容
+1
WIN32SDK_ASM 2014-07-25
  • 打赏
  • 举报
回复
引用 13 楼 xhw88398569 的回复:
引用 3 楼 liuxiaohailxh8888 的回复:
改写常量需要用memset
我居然信了,还好测试了一下
恩,确实是错的,当我发完帖子突然发现是错的但是编辑不鸟帖子了
赵4老师 2014-07-25
  • 打赏
  • 举报
回复
引用 14 楼 xhw88398569 的回复:
[quote=引用 10 楼 zhao4zhong1 的回复:]
#pragma comment(linker,"/SECTION:.rdata,RW")
//加这句可以让常量区可写,后果自负!
还是不可以写啊,linux下测试的[/quote] 这是windows下的。
赵4老师 2014-07-24
  • 打赏
  • 举报
回复
#pragma comment(linker,"/SECTION:.rdata,RW")
//加这句可以让常量区可写,后果自负!
鼻涕虫de皮皮 2014-07-24
  • 打赏
  • 举报
回复
貌似向常量区写东西了
virtualxmars 2014-07-23
  • 打赏
  • 举报
回复
这一句:

char *p = "WanG";
因为"WanG"对编译器来说实际上是一个常量,也就是不允许变化的量,所以将其赋值给char *p是不对的,因为 char * 实际上指出p是可以被修改的。而"WanG"其实会被放在不可编辑的全局符号表位置。那么你后面的修改就是非法的了。 解决办法是:

    char name[] = "WanG";
    char *p = name;
由于引入了数组,所以"WanG"会定义在函数的堆中,这样,它就变成了可被修改的内容
WIN32SDK_ASM 2014-07-23
  • 打赏
  • 举报
回复
改写常量需要用memset
zhousitiaoda 2014-07-23
  • 打赏
  • 举报
回复

char q[10] = "WanG";
	char* p = q;
赵4老师 2014-07-23
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
这不是鸭头 2014-07-23
  • 打赏
  • 举报
回复
字符串常量。基础
707wk 2014-07-23
  • 打赏
  • 举报
回复
引用 2 楼 zhousitiaoda 的回复:

char q[10] = "WanG";
	char* p = q;
+1 字符串常量不能被修改,如果你硬要修改的话有方法@赵老师
木木口口 2014-07-23
  • 打赏
  • 举报
回复
char *p = "WanG"; 这样定义一个常量字符串,是没办法用=赋值来改变的
mujiok2003 2014-07-23
  • 打赏
  • 举报
回复
  char *p = "WanG"; // read only 
//...
*p =  tolower('D'); //oops
勤奋的小游侠 2014-07-23
  • 打赏
  • 举报
回复
char* p和 char p[]的最大区别就是一个是const,一个不是。

69,364

社区成员

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

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