我可以在其范围之外使用声明为局部变量的数组值吗?

时间:2015-04-12 18:36:23

标签: c variables pointers scope local-variables

假设以下简单代码:

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之外的字符串

如果没问题,为什么会这样?

4 个答案:

答案 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访问(读取)该数据。但是,尝试写入该位置将导致分段错误。