请教:char *p="abcdef"和char s[]="abcdef"存储在哪里的问题!

菜鸟老吴 2008-11-06 11:57:45
加精
#include <stdio.h>
int main()
{
char *p="abcdef"; //很多书上说:p在栈,“abcdef”在数据区
p[2]='W';
printf(p);
getchar();
return 0;
}
这个程序编译通过,但是问什么程序运行会出错?

另一个:
#include <stdio.h>
int main()
{
char s[]="abcdef";//s在栈,“abcdef”在数据区
s[2]='W';
printf(s);
getchar();
return 0;
}
这个程序能够正常输出!


请问这是为什么?
p,s和“abcdef”分别在那个区?
...全文
7682 179 打赏 收藏 转发到动态 举报
写回复
用AI写文章
179 条回复
切换为时间正序
请发表友善的回复…
发表回复
yizhengtutu 2012-09-10
  • 打赏
  • 举报
回复 1
[Quote=引用 8 楼 的回复:]

char s[]="abcdef";//这是告诉编译器,要用一个字符数组,里面放上“abcdef”这个内容(编译器开一个空间放上字符数组的内容)
char *p="abcdef"; //这个是告诉编译器,要用一个指针(编译器开一个空间放指针),让指针指向放着“abcdef”内容的地方,eoh,这时候没为“abcdef”开空间,那编译器就认为这个是常量字符串了,自己把它放常量区里,让指针指向常……
[/Quote]

受教了
BYD123 2012-09-08
  • 打赏
  • 举报
回复
1)char s[] = "abcdef",程序在运行前会把把"abcdef"拷贝到栈里,即s的内存区域(栈);
2)char *p = "abcdef",运行前没有为指针分配空间,指针指向程序的常量区。
maben10080416 2012-08-30
  • 打赏
  • 举报
回复
char *p="abcdef"; 说p在栈区,“abcdef”是对的,指向常量的指针是不可以通过指针移动去修改指针所指内容的

char s[]="abcdef";//s是在栈,但这时的“abcdef”应该是在堆区,因为这里'[]'操作符已经说明是动态分配了,所以肯定是堆区。而则个s指针没有被const* 修饰,所以指向的也不是常量,可以通过指针移动改变指向的内容。
Flammable_ice 2012-08-25
  • 打赏
  • 举报
回复
经典的问题哦 学习了!
xder125 2012-08-11
  • 打赏
  • 举报
回复
char * a="abc";
由于abc放在静态区,在debug模式下很难通过a指针对某位置赋值。但在release模式可以通过。查看了一下网上资料:debug版本调试不做任何优化,而release需要进行了各种优化,另外C\C++允许打破任何保护,所以发布版本发现不了错误。
yaoyu20_xg 2012-07-03
  • 打赏
  • 举报
回复
典型问题必需MARK
yhcelebrite 2012-04-14
  • 打赏
  • 举报
回复
这也行,crazy!
ioaq 2012-04-13
  • 打赏
  • 举报
回复
好多高手啊
zhaohongbo84 2012-03-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 r9r9r9 的回复:]
char *p="abcdef"; //"abcdef" 静态存储区,是常量区,不可改, p[2]企图通过p这个指针改变常量区的内容,所以你这个程序编译通过,运行会出错?

char s[]="abcdef";//"abcdef" 静态存储区, 你赋值给s[]这个变量后,改变s[2],所以不出错。


p, s 在同一个区,如果是局部变量,就是在栈里面。
"abcdef"; //静态……
[/Quote]



2L 讲的非常好 ~
永远北极 2012-03-05
  • 打赏
  • 举报
回复
真是不错的分析讨论,受教了
jinxiao20 2012-03-03
  • 打赏
  • 举报
回复
mark学习下
unionazbdf 2012-02-03
  • 打赏
  • 举报
回复
冒充一下高手:
char *p="abcdef"; //很多书上说:p在栈,“abcdef”在数据区
p[2]='W';
这个程序编译通过,但是问什么程序运行会出错?
这个p是一个指向char类型的4字节地址,临时变量,存放于栈中,比方它的数值是0x00000001,指向"abcdef"首地址,那么p[2]是不是指向"abcdef"中的c呢?不是的,p[2]等于2+&p,这个地址是p的地址的下2字节,注意:并不是0x00000003!比如&p是0x00000100,那么p[2]等于0x00000102,这个值可能位于栈中,如果对0x00000102这个字节修改成'W',即改变了函数的进出栈操作,造成访问违规,或不可预期的操作,总之对应指令错误。"abcdef"这里头的c的地址应该是p+2,*(p+2) = 'W',应该会编译报错,因为这时候才指向的是"abcdef"中的'c',及全局数据常量区,只读。

另一个:
char s[]="abcdef";//s在栈,“abcdef”在数据区
s[2]='W';
这个只是简单的初始化一个数组而已,p应该指向栈中的"abcdef"存储区,&p也应该位于栈区。
hjrui09 2012-01-26
  • 打赏
  • 举报
回复
本人在linux下看到的"abcdef"首地址是在代码区。
hjrui09 2012-01-26
  • 打赏
  • 举报
回复
哦哦!
gz_eddie_htc 2011-12-10
  • 打赏
  • 举报
回复
受益匪浅~mark~mark~
猪头小哥 2011-12-08
  • 打赏
  • 举报
回复
学习了~~~这个问题很底层了 觉得~~
zhujian888 2011-11-18
  • 打赏
  • 举报
回复
每天签到得10分。
wxt_linux 2011-11-18
  • 打赏
  • 举报
回复
char *p="abcdef";p是一个指针常量,它指向的内容不能改变
p[2]='W'; 这是错误的

char s[]="abcdef";s是一个常指针,它指向的内容可以改变
s[2]='W';
sdudubing 2011-11-14
  • 打赏
  • 举报
回复
好帖子,学习了
赵4老师 2011-11-14
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。

#pragma comment(linker,"/SECTION:.rdata,RW")
加载更多回复(160)

69,373

社区成员

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

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