首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

求教一个关于堆栈内存和静态内存的指针的有关问题

2013-12-13 
求教一个关于堆栈内存和静态内存的指针的问题下面两段资料上的例子 有点乱请大家谅解char *f(void){ char

求教一个关于堆栈内存和静态内存的指针的问题

下面两段资料上的例子 有点乱请大家谅解
char *f(void)
{
 char *str="hello world";

return str;
}
char * a=NULL;
a=f();
 

char *f(void)
{
 char str[]="hello world";

return str;
}
char * a=NULL;
a=f();
第一个正确第二个错   是因为第一个f返回的是指向静态数据区的指针 第二个是指向堆栈内存的
但是我又做了下面的测试
char *f(void)
{
 char *str=new char[10];
 strcpy(str,"abc");

return str;
}

为什么这个也是正确的?str不也是指向堆栈内存的指针吗?为什么在函数外还能访问?还是我理解错误?
还有关于上面说的静态数据区 我又做了下面的测试
char *f(void)
{
char str[]="abc";
  char *str2="hello";
cout<<&str<<endl;
cout<<&str2<<endl;
cout<<&"hello"<<endl;
return str2;
}
然后发现str2指针的地址并不在静态区 ,而是在堆栈内存 ,与str的地址紧挨着 ,而且也与“hello”的地址不同(“hello"是在静态数据区) 同样是在静态区 为什么只有str2能在函数外访问?
请问这个应该怎么理解?
[解决办法]
1 可以是应该把常量字符串的地址赋值返回的!函数结束了地址还是有效的
2 局部地址函数结束后,内存也就是释放了,所以很危险的动作,可以说是错误的
3 堆内分配的内存地址,只要程序没结束,没有手动delete,内存一直存在的,
  函数返回这块内存的首地址,然后通过地址正常访问


cout<<&str<<endl;// 这个打印的地址不是str指向的地址,而是存放指针本身的地址
   cout << (void *)str << endl; //这个才是指向的地址 ,"abc"的首地址
cout<<&str2<<endl; //同上面。这个也是指针本身存放的地址,而这些都是存放在栈空间的
  cout <<(void *)str <<endl; //这样打印出来地址才是"hello"的地址,也就是静态区的地址了

return str2;

[解决办法]
堆和栈要分开呀.
平时说的堆栈实际都是指栈内存, 即你的char str[]="hello world"; 这是栈上分配的.

而动态申请的, 比如new, malloc等等, 这是在堆上申请的.

所以char str[]="hello world"; 与 char *str=new char[10];是不同的东西.

栈上分配的东西生命周期是在{}限定的作用域内.
而堆上分配的, 只要你不释放, 可以持续到程序结束.
[解决办法]
不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质,
而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。

热点排行