Chinaunix首页 | 论坛 | 博客
  • 博客访问: 232095
  • 博文数量: 37
  • 博客积分: 933
  • 博客等级: 军士长
  • 技术积分: 511
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-16 10:15
文章分类
文章存档

2012年(1)

2011年(36)

分类: C/C++

2011-05-03 13:35:23

设想这样一种情况:
在file1.c中定义如下数组:
  1. char str[10] = {1,2,3,4,5,6,7,8,9,10};

而在另一个文件file2.c中想要引用此数组数据却如此声明:

  1. extern char *str;

这样的错误及其常见。如果运行含有此代码的程序,一般会segment fault。这也是最好的结果。经过后面的说明后,你会理解为什么说这样是最好的结果。

想要弄明白这个问题的根源,需要理解数组和指针的访问方式区别。

在定义一个数组后,我们可以通过str[2];来访问其中的元素;

而定义一个指针后,我们也可以通过str[2];来访问其中的元素,但是访问的方式却是大相径庭的。

了解了上述的访问方式的区别后,我们看一下

char str[10] = {1,2,3,4,5,6,7,8,9,10};

extern char *str;

由于我们认为在file2.c中指定str是一个外部指针,那么编译器就会以访问“指针所指向的元素的方式”访问元素。同时我们也知道,str这种符号的地址是在编译时期就确定的。而此时这个符号的地址正好是str数组的第0个元素的地址(即str[0]的地址)。所以在file2.c中访问str[1]时,会先找到str符号的地址取其内容再加上1然后解引用。就是要访问的元素。

而此时,数组符号地址对应的内容为1(str[0])--->0x00000001 + 4(bytes)去访问这个地址的内容,当然会segment fault了。

我们可以做一个实验,把str[0]内存单元的内容填写为一个变量的地址 - 1 然后去利用指针去访问。

file1.c

  1. #include<stdio.h>
  2. int p = 9999;
  3. int str[10] = {&p - 1,2,3,4,5,6};

file2.c

  1. #include<stdio.h>
  2. extern int *str;
  3. int main()
  4. {
  5.         int a = str[1];
  6.         printf("%d\n",a);
  7.         return 0;
  8. }
通过这段代码应该很好理解上述问题的原因了。究其根本:就是由于访问方式的不同所造成的。
阅读(2720) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~