|
主题 : : 请教:char *p="abcdef"和char s[]="abcdef"存储在哪里的问题! [待解决] |
回复[ 8次 ]
点击[ 1269次 ] | |
|
|
|
|
[帖 主]
[ 发表时间:2008-11-09 17:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26 |
#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”分别在那个区? | | |
|
|
|
|
[第1楼]
[ 回复时间:2008-11-09 19:12 ]
[引用]
[回复]
[ top ] | |
荣誉值:18
信誉值:0
注册日期:2008-08-31 11:07 |
char *p="abcdef";
字符数组的字面值("abcdef")是被编译器作为一个常量字符数组建立的,修改该字符数组的任何字符都会导致运行时错误,我记得gcc编译器会有警告的。 | | |
|
|
|
|
[第2楼]
[ 回复时间:2008-11-14 14:19 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-07-19 20:02 |
在TC中测试发现char *p="abcdef";中字符串的确当字符数组常量对待,如果在保护模式下的编译器编译此程序,将会发生段访问异常.而在第二个程序中,字符串是放在栈中的,而在保护模式下,栈段是可写的. | | |
|
|
|
|
[第3楼]
[ 回复时间:2008-11-25 19:45 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2008-11-08 12:33 |
第一个程序可以通过编译,只要你将编译环境设为支持中文就可以了; | | |
|
|
|
|
[第4楼]
[ 回复时间:2009-03-03 22:21 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2008-04-01 22:25 |
一般认为,内存分为 堆区,栈区,代码区,字符串常量区。对与程序中的局部变量,都在栈空间中分配内存,而对于 malloc 和 new 这些动态内存分配,则都在堆区分配。
第一个程序:
char *p="abcdef"; p 在栈区, "abcdef"存在于字符串常量区,试图修改一个字符串常量的值,故运行时会错。
第二个程序:
char s[]="abcdef"; 数组s在栈里面分配了内存,然后将“abcdef”赋给数组 s,即“abcdef”也在栈区,它不是字符串常量了,所以 s[2]='W';是可以修改那块内存空间的数据的。 | | |
|
|
|
|
[第5楼]
[ 回复时间:2009-03-03 22:37 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:2
注册日期:2008-04-01 22:25 |
更正一下,c/c++中,内存可分为:栈区,堆区 ,全局区(静态区)--用于存放全局变量和静态变量,文字常量区--像 "abcdef"就存放在这,程序代码区--用于存放代码。 | | |
|
|
|
|
[第6楼]
[ 回复时间:2011-06-22 13:40 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-06-22 13:20 |
|
|
|
|
|
[第7楼]
[ 回复时间:2011-06-22 13:40 ]
[引用]
[回复]
[ top ] | |
荣誉值:0
信誉值:0
注册日期:2011-06-22 13:20 |
|
|
|
|
|
[第8楼]
[ 回复时间:2011-06-22 13:57 ]
[引用]
[回复]
[ top ] | |
荣誉值:10
信誉值:6
注册日期:2011-06-01 16:20 |
建议:反汇编一下看看~~ 这是最好的。
(不过在32位上的汇编传递参数、局部变量都是用的栈,用法就是mov [ebp+N],xxx和ret N。在书上的附注里面有,可以看下。) | | |