昨天看到strcpy函数的典型实现时,发现该函数的返回值为局部指针变量,当时产生疑问:局部指针在函数结束时不是会被注销掉吗?为什么此处没有呢?
下面给出strcpy函数代码:
char* Mystrcpy(char* strDest, const char* strSrc)
{
assert((strDest!= NULL)&&(strSrc != NULL));
char* adress = strDest;
while ((*(strDest++) = *(strSrc++)) != 0);
return adress;
}
后来在一篇博文中找到了答案,文章网址为:http://blog.csdn.net/summer_liuwei/article/details/6423219。
下面我将我的理解结合堆栈来解释一下:
首先解释一下C++中各种变量的存放位置,经常需要操作的内存可分为:栈区(存放函数的参数值,局部变量值等)、堆区(一般是由程序员分配的空间)、全局/静态变量区(存放全局变量和静态变量,分为初始化区域和未初始化区域)、文字/只读常量区(存放常量字符串)、程序代码区(即代码段)。
int a = 0; //全局变量(全局初始化区域)
char* p1; //全局指针变量(全局未初始化区)
void func(char* para)
{
int b; //局部变量(栈区)
char s[] = "abc"; //s[]的所有元素保存在栈上,s只是个符号地址没有内存空间,
//所以在函数结束时,"abc"被析构掉,s的指向不定
char* p2; //局部变量(栈区),由于其未初始化,其指向不定。
//若是p2=para,则在程序结束时,p2依旧指向该区域(因为para指向的内存不在该函数的管辖内)
char* p3 = "12345"; //p3在栈上,但12345在文字常量区,所以在函数结束时,"12345"不会被析构掉,p3仍指向该区域
static int* c = 0; //静态变量(静态存储区)
p1 = new char[10]; //程序员分配的内存在堆上
}
上面代码给出了一些解释,现在回到一开始的问题,为什么 局部指针 adress 在函数结束时仍然指向strDest的初始地址?因为strDest所指向的内存在strcpy函数结束时不受影响,所以adress自然不会变。