读林锐博士《高质量程序设计》的困惑

jiangtianyin 2009-01-12 07:46:36
书中11.4节有这样一段话
char *GetStringA(void)
{
char p[]='hello word!";
return p;//编译器将提出警告
}
void test4(void)
{
char *str=NULL;
str=GetStringA();//str的内容将是垃圾
cout<<str<<endl;
}
-------------------------------------------------------
char *GetStringB(void)
{
char *p="hello Word!";
return p;
}
void test5(void)
{
char *str=NULL:
str=GetStringB();
cout<<str;
}
书上解释说:test4 中return返回的是栈内存,内容是垃圾,test5运行不会错,但设计理念是 错误的,因为GetStringB()内的“hello Word”是常量字符串,位于静态存储区,它在程序生命期内恒定不变,所以每一次调用GetStringB()返回的始终是同一个“只读”内存。

问题:GetStringA()中的char p[]="hello word!"; 和GetStringB()中的char *p="hello world!"有什么区别,其中“hello World"应该都是常量字符串,都位于静态存储区,但为什么前面一个返回的是栈内存,后面一个不是呢?难道char p[]和char *p不同吗?
...全文
297 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
yndfcd 2009-01-13
  • 打赏
  • 举报
回复
GetStringB在真实的代码中有大量的应用,设计理念有问题,还是林锐的脑子有问题?
jackzhhuang 2009-01-13
  • 打赏
  • 举报
回复
书里面已经说得很明白了

char[]申请了栈内存,函数结束后就还给系统了

而char*是一个指针指向只读区,它是放在全局的,返回后的地址一直是有效的,所以没事。
InfidelX 2009-01-13
  • 打赏
  • 举报
回复
char p[]分配了内存空间存储在栈上,出了char p声明的作用域(也就是那对花括号)之后,这个变量自动被系统回收,返回的地址中的内容不可预测
char *p 没有分配内存空间,如果赋值,这个值只能放在常量区,当然无法修改。
effective100 2009-01-12
  • 打赏
  • 举报
回复
这样的问题,在论坛碰的次数太多了。建议楼主看看 《C++ 对象模型》
060 2009-01-12
  • 打赏
  • 举报
回复
可以看看变量的地址, 了解它们在什么位置

char *GetStringA(void)
{
char p[]='hello word!";
char p2[16];
printf("1: 0x8x\n", p);
printf("1.1: 0x8x\n", p2);
return p;//编译器将提出警告
}


char *GetStringB(void)
{
char *p="hello Word!";
char p2[16];

printf("2: 0x8x\n", p);
printf("2.1: 0x8x\n", p2);
return p;
}

int a;
int b = 0;
char* c = "HHH";
int main()
{
printf("3: 0x8x\n", &a);
printf("4: 0x8x\n", &b);
printf("5: 0x8x\n", c);

}
feng4206yu 2009-01-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 nullah 的回复:]
问题:GetStringA()中的char p[]="hello word!"; 和GetStringB()中的char *p="hello world!"有什么区别,其中“hello World"应该都是常量字符串,都位于静态存储区,但为什么前面一个返回的是栈内存,后面一个不是呢?难道char p[]和char *p不同吗?

char p[] = "hello,world";
在栈上申请开辟空间,然后空间的变量值赋值初始化为hello,world
如果是char *p;
为了节省空间p是直接指向常量存储区的常量字符的
[/Quote]
我补充:1.函数在栈上开辟空间,然后在函数返回值后由于函数生命期结束,栈上的东西会被清空,即char p[]="hello word!"; 会被销毁,所以GetStringA()返回的地址指向的内容已不是期望的了,这片内存可能会被用作他用,对str来说就是垃圾了...
2.char* p = "hello,world";因为在c++中,编译器一般将字符串常量放在全局区,所以GetStringB()返回的地址有效,但是注意全局区的东西是不可修改的,这就是str指向的东西不可修改,即设计理念是错误的..
另:5楼的说法是不负责任的..
ttklboy 2009-01-12
  • 打赏
  • 举报
回复
应该是申请一块内存 不好意思打错了
ttklboy 2009-01-12
  • 打赏
  • 举报
回复
简单的说 函数内定义的变量在函数结束后都会销毁
GetStringA()中定义的是一个字符串,这个函数把字符串首地址返回,然后函数结束,这个字符串就被销毁了,也就是这个字符串的内存被收回了

而GetStringB()中定义了一个字符串的指针,执行char *p="hello Word!"时,程序为"hello Word!"这个字符串申请了一块地址,并把这块地址的首地址放在指针p 中。当函数结束时,被销毁的是指针p,而字符串不会消失,并且首地址已经返回到函数的调用者
squallleonhart 2009-01-12
  • 打赏
  • 举报
回复
char* p = "hello world"; //p是一个字符串指针,指向常量字符串"hello world"
char p[] = "hello world"; //p[]是一个字符串数组,声明数组后取得常量"hello world"并赋值给数组。
xiaoyisnail 2009-01-12
  • 打赏
  • 举报
回复
GetStringA()里在栈上分配了字符数组p,并用"hello world",数据在栈上的,所以函数退出后栈上的数据就被销毁了,函数外部访问返回的str时访问的是垃圾
GetStringB()只是在栈上分配了一个字符指针p,指向常量存储区上的字符串常量"hello world",返回值是栈上指针p,赋值给str,所以str也指向常量存储区上的字符串常量"hello world",所以输出正确数据
waizqfor 2009-01-12
  • 打赏
  • 举报
回复
char p[]和char *p不同吗?
有很大的不同
char p[]分配了内存空间 存储在栈上 可以随便改变字符串中的内容
char *p 没有分配内存空间 如果赋值 是存储在常量区 也就是只读型的 不能修改
这问题 几乎天天都有人在问
nullah 2009-01-12
  • 打赏
  • 举报
回复
问题:GetStringA()中的char p[]="hello word!"; 和GetStringB()中的char *p="hello world!"有什么区别,其中“hello World"应该都是常量字符串,都位于静态存储区,但为什么前面一个返回的是栈内存,后面一个不是呢?难道char p[]和char *p不同吗?

char p[] = "hello,world";
在栈上申请开辟空间,然后空间的变量值赋值初始化为hello,world
如果是char *p;
为了节省空间p是直接指向常量存储区的常量字符的

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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