函数内创建的数组在调用后,是不是就不存在
本帖最后由 test_lockxxx 于 2014-04-23 09:31:06 编辑
第1种写法:
char *getABC()
{
char str[10];
strcpy(str,"12345");
return str;
}
void main()
{
char *p = getABC();
printf("%s\n",p); //这样正确吗?p 指向的位置是不是已被 自动释放了,
}
第2种写法
void getABC(char *pStr)
{
strcopy(pStr,"123456");
}
void main()
{
char str[10];
getABC(str);
printf("%s\n",p); //这样正确吗?
}
------解决方案--------------------
第二种正确(如果不是写错的话)
c是一种比较靠近底层的语言。
------解决方案--------------------
第一种返回了局部变量的地址,这个地址指向的内容在函数结束后可能被修改,所以你取p的值的时候可能会得不到你想得到的内容
------解决方案--------------------
生命周期的问题。 可以在堆上申请空间。
------解决方案--------------------
就回收了的 栈就是这样
------解决方案--------------------
验证了一下:
写法1,打印出来的是乱码。 --- 数组被释放了,该内存地址内容是随机的,str[10]是全局变量就不存在问题。
方法2,是对的,指针传递。 不过有两处语法错误。
------解决方案--------------------
这样也对:
char *getABC()
{
static char str[10];
strcpy(str,"12345");
return str;
}
void main()
{
char *p = getABC();
printf("%s\n",p); //这样正确吗?p 指向的位置是不是已被 自动释放了,
}
------解决方案--------------------
建议你去看看数据的存储,这就是一个数据存储类型的问题
------解决方案--------------------
你想知道的是这些?
用这样的方式,如
int a[16]
这个数组是被当作直接存取的数据,生命周期在作用域内,过了就不存在了。
但是如果用
int * a =new int[16];
这个数组需要手动释放,这就是C++反对者会说C++不好的原因之一了
但是需要知道
a 本身也是个 UNIT变量,所以如果这句话在函数中出现,那么 a 的生命周期也是这个函数体。
但是a指向的数组内存是一直存在的,需要手动释放。
PS:你问的这个问题,和堆栈关系不大。
------解决方案--------------------
char *getABC()
{
char str[10];
strcpy(str,"12345");
return str; //理论上,这是错误的
}
void print_data()
{
char str[80];
printf("str=%p",str);
}
void str_test()
{
char str[10];
char *s,*t;
char *p = getABC();
register int i;
for(s=p,t=str,i=0;i<10;i++)
*t++=*s++; //这么处理,可以勉强把数据复制出来,而不错误
printf("%s\n",str); //输出是正确的,但是从C语言来说,却是错误的;
//因为返回的数组地址,是个超过生存周期的数组的地址,
//这个地址对应的内存,可能会另作他用比如,局部变量,调用函数传递的参数,函数返回地址等等
//这里 .str,"%s\n" 这两个参数,以及printf函数的局部变量;
//可能会占用p这个指针表示的地址.
//所以输出可能不正确.
printf("p = %p,",p);
}
------解决方案--------------------
第二种方法是正确的,因为strcpy的字符串实际上是拷贝到了main函数的数组str中。所以,在main函数里可以正确输出拷贝后的字符串。
------解决方案--------------------
char *getABC()
{
char *str="12345";//这样也对
//strcpy(str,"12345");
return str;
}
void main()
{
char *p = getABC();
printf("%s\n",p); //这样正确吗?p 指向的位置是不是已被 自动释放了,
}