C语言中字符数组和字符指针的问题

char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

这个程序,运行Tesxt()函数,结果是乱码,答案解释如下:
因为 GetMemory 返回的是指向“栈内存”
的指针,该指针的地址不是 NULL,但其原
先的内容已经被清除,新内容不可知。

可是我把GetMemory函数中的char p[]="hello world"改成char *p="hello world"; 就可以正常输出hello world 了。

我的问题是,子函数中定义的数组的生存期跟子函数的生存期相等,那子函数中定义的指针的生存期呢,是否也和子函数的生存期相等?

帮我解决了问题我加分给大家!

未修改之前char p[] = "hello world";中的字符串"hello world"空间开辟在在动态变量区(栈上),而该动态变量是局部的,函数结束时不保留的。
把char p[]="hello world"改成char *p="hello world"; 后,字符串"hello world"不是变量,而是一个常量,编译程序在处理这种常量时,通常把它放在了常量区中。而常量区则是始终存在的。
所以返回首地址后,在外部还可以继续访问该常量,所以就能打印出来。

函数返回指针,要使主程序可以使用这个指针来访问有意义的数据,关键就是要保证在使用这个指针值的时候,该指针所指向的地方的数据仍然有意义。
还有,如果指针是指向函数的指针,那么这个指针就是指向程序代码区的。这也是一种应用的情况。
另外,如果明白了它的原理,程序员还可以发明出一些其他灵活的使用方法,当然,那都属于“怪”方法,一般不提倡的。
温馨提示:内容为网友见解,仅供参考
第1个回答  2015-12-08
在函数内 char[]数组被定义成局部变量,函数运行后会被系统给释放掉。 但char*p 则是定义成一个常量,程序运行完后才会释放掉。所以在返回char p[] 时会返回乱码,但 char*p 则可以全部显示出来
当然 char[] 也可以定义成静态变量 这样就可以显示出来了
不如
static char[] p="hello";
第2个回答  2011-12-28
也许在函数返回时把函数中生成的数组所占用的空间收回或者覆盖了别的内容。
而仅仅是指针指向的地址可能不在栈上开辟,那么即使函数中定义的指针被回收了,该指针指向的地址也没有回收。你可以编程试试。那个p指针所在的地址肯定回收了,但是p指针指向的地址可能没有回收或者回收了没有覆盖它。
要么是'\0'的问题,加个'\0'试试看。
第3个回答  2011-12-28
指针本身没什么生存期,它指向的内存的内容才有生存期。
换成char *p="hello world"之后,之所以可以正常输出“hello world”,我的理解是,编译器在静态存储区申请了一段内存,就算GetMemory返回了,这段内容依然有效,所以能正常输出。
而char p[]="hello world",p指向的是栈,函数返回这段内存就会无效。
第4个回答  2011-12-28
赞同jzp1的分析,我再举个jzp1说的不规范的使用方法,该返回一样可以打印出字符串:
char *GetMemory(void)
{
static char p[] = "hello world";
return p;
}
int main(int argc, char* argv[])
{
char *str = NULL;
str = GetMemory();
printf(str);
return 0;
}

关于C语言字符串数组和字符指针相互赋值问题
首先:char filename[50]="C:\\\\RequestData";这句涉及到指针强转,会将filename指向"C:\\\\RequestData"所在的地址,在对filename进行操作时就有可能崩溃。其次:char * fileArray[56];是指针数组,存储了56个char *型指针,而你这样儿fileArray[i] = filename;进行赋值是指针赋值,故fileArray中...

字符串数组与字符指针的区别
C语言有两种表示字符串的方法,一种是字符数组,另一种是字符串常量,它们在内存中的存储位置不同,使得字符数组可以读取和修改,而字符串常量只能读取不能修改。三、存取效率 char *a = “abcd”; 存于静态存储区。在栈上的数组比指针所指向字符串快,因此慢。而char a[20] = “abcd”; 存于...

一个C语言中指针型字符数组的问题
char *p=“AAA”; \/\/初始化一个指向字符串的指针(指向字符串其实是指向字符串的第一个字符)注意,上面说的是指向字符串常量!p[0]='B'; \/\/不允许 这会导致内存访问错误。原因在于编译器可能选择内存中的同一个单个的拷贝,来表示所有相同的字符串文字。给你举个例子:char message1[] = ...

关于C语言的字符串指针的问题?
如果输入12345,那么p指向1,即p中存放着1的地址。没有字符串的指针和指针指向的内容不能修改一说。无论什么类型的指针,只要是“常指针”就有三种情况不可改变:指针是常量——这个指针只能指向申明时指向的目标,不能指向别处。指向的内容是常量——不能通过这个指针改变指向的内容,但指针可以指向别处...

关于字符串和指针的问题
A错。s是数组,p是指针,虽然在使用上没差别,但毕竟是两个不同类型。B错。p中的内容是s的首地址,而s中的内容指的是china这个字符串。D错。s的长度是算上了字符串结束符,是6。p指向的字符串长度是5,不包括结束符 28。C A错。str本身就是地址了,不用加& B错。p未初始化 D错。p[2]...

C语言字符指针问题
printf("%c", *p); \/\/ 结果是hprintf("%c" , *(p+1)) \/\/ 结果是e最后是函数引用问题。这里是否能引用p,是需要看你的函数是怎么写的。比如说你说strcmp。他的原型为 extern int strcmp(const char *s1,const char *s2);他两个参数均为指针,当然可以直接使用p这个指针作为参数 ...

解惑丨C语言字符串常量、字符数组、字符指针!
字符指针与字符数组类似,都是指向字符的指针。例如,声明一个字符指针`const char* b = "321";`,表示`b`是一个指向字符串常量`"321\\0"`的指针。由于`b`是一个指针,它存储的是字符串常量的地址,而非内容。在C语言中,`const`关键字用于声明指针指向的是常量,即指针所指向的内存内容不可...

字符指针变量和字符数组的区别
字符(非字符串数组,字符数组和字符串数组是有区别的,字符串数组每个元素都是一个字符串)数组是用来存放字符的数组,在内存中占一段连续的单元。所占内存存放的是字符串。定义方法为:char a[N];N为常量表达式,可初始化。字符指针是指向字符的指针,所占内存单元存放的是所指字符的内存单元。定义...

C语言指针、字符串、取反问题
1、第一题的答案纯属误导,坚持你的意见就行 2、char a[7]="a0\\0a0\\0";这个你要注意,strlen碰到'\\0'后就会以为串已经结束,并返回,所以碰到第一个\\0时就返回长度2了 至于那个空格,应该没有吧,我在vc里面直接就编译不过去 3、只要你单引号里面能表示为一个字符就行,而数字,看起来是...

C语言中字符指针的问题 char *pointer = "Hello World!"; printf...
回答:这里的 pointer 指向的是一个字符串,字符串的首地址赋给 pointer printf("%s\\n",pointer); \/\/输出Hello World!\/\/ printf 遇到指向字符串的指 \/\/针时,输出字符串(就是这样定义的) printf("%s\\n",*pointer); \/\/输出H printf("%d\\n",pointer); \/\/输出pointer指向的地址

相似回答