假设以下简单代码:
int main(void){
char *p;
int i = 1;
while(i){
char str[] = "string";
p = str;
i = 0;
}
/* Can I use above string by using `p` in here? */
return 0;
}
我将一个字符串(char数组)声明为仅在while{}
中有效的局部变量。但我将其数组地址保存到指针p
,该指针在while{}
之外也有效。是否可以使用while{}
p
之外的字符串
如果没问题,为什么会这样?
答案 0 :(得分:1)
使用
while{}
可以使用p
之外的字符串吗?
否即可。在while
p
的范围内指向str
的第一个字符。在while
之外没有str
因此没有p
指向的有效内存位置。
使用static
声明中的str
存储类说明符
static char str[] = "string";
在while
之外,您可以使用p
printf("%s\n", p);
这是因为块中声明的static
变量在整个程序执行期间驻留在同一存储位置。
答案 1 :(得分:0)
不,这不行。这就是所谓的悬空指针。如果您在程序尝试重用此地址之前设法使用内存,则仍可能获得预期结果。但是,如果再次使用内存,您将获得意想不到的结果和很难找到的错误。
答案 2 :(得分:0)
试试这个例子,它可能不适用于所有编译器,但在OS X上的Xcode中我得到了这个结果:
pa:苹果
pa:橙色
po:橙色
#include <stdio.h>
char *pa;
char *po;
void apples(void)
{
char sa[]="apples";
pa = sa;
printf("pa: %s\n", pa);
}
void orange(void)
{
char so[]="orange";
po = so;
printf("pa: %s\n", pa);
printf("po: %s\n", po);
}
int main(void)
{
apples();
orange();
return 0;
}
对apples()和orange()的每个函数调用随后增长,然后收缩堆栈,你可以看到字符串( apples 或 orange )的结果如何在堆栈上的相同内存位置。但是,一旦超出范围,字符串就会存在零保证。这个技巧&#34;工作&#34;在这里,但这是非常危险的。
作为一个额外的练习,尝试在调用orange()之后在main()中打印 po 的内容,在大多数情况下,当调用printf()时,字符串将会消失。堆栈上的空间。
答案 3 :(得分:-1)
str指向进程的只读(数据)区域。您也可以使用p访问(读取)该数据。但是,尝试写入该位置将导致分段错误。