结构成员 - 地址重叠

时间:2013-11-06 08:12:37

标签: c arrays memory-management structure

在这个程序中,我已经声明了一个结构以及很少的成员,并且我使用了两个元素的数组作为这个特定结构的实例。我在这个结构中使用了5元素数组。一个奇怪的是,在main函数中,当我尝试获取5元素数组的不存在的第6个元素的地址时,我得到下一个结构的第一个成员整数的地址。为什么当我尝试访问一个不存在的数组元素并且为什么两个成员具有相同的地址时没有显示错误?

#include<stdio.h>
 struct {int num1,num2; char s1; int *ptr; int abc[5]; }a[2];

void main(){

      int start, last; 

      start = &a[1].num1;

      last = &a[0].num1;

      printf("\nSize of the Structure : %d Bytes", start-last);

      printf("\naddress of num1 in structure a[0] is %d", &a[0].num1);

      printf("\naddress of num2 in structure  a[0] is %d", &a[0].num2);

      printf("\naddress of char in structure a[0] is %d", &a[0].s1);

      printf("\naddress of ptr in structure a[0] is %d", &a[0].ptr);

      printf("\naddress of I element in array abc[5] in structure a[0] is %d", &a[0].abc[0]);

      printf("\naddress of II element in array abc[5] in structure a[0] is %d", &a[0].abc[1]);

      printf("\naddress of III element in array abc[5] in structure a[0] is %d", &a[0].abc[2]);

      printf("\naddress of IV element in array abc[5] in structure a[0] is %d", &a[0].abc[3]);

      printf("\naddress of V element in array abc[5] in structure a[0] is %d", &a[0].abc[4]);

      **printf("\naddress of VI element in the 5 element array abc[5] in structure a[0] is %d", &a[0].abc[5]);

      printf("\naddress of num1 in structure a[1] is %d", &a[1].num1);**

      printf("\n");


  }

kevin@kevin-desktop:~/Documents/programs$ gcc --version
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3
Copyright (C) 2009 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

kevin@kevin-desktop:~/Documents/programs$ gcc structure_size.c -o structure_size
structure_size.c: In function ‘main’:
structure_size.c:15: warning: assignment makes integer from pointer without a cast
structure_size.c:17: warning: assignment makes integer from pointer without a cast
structure_size.c:21: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:23: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:25: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘char *’
structure_size.c:27: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int **’
structure_size.c:29: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:31: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:33: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:35: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:37: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:39: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
structure_size.c:41: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘int *’
kevin@kevin-desktop:~/Documents/programs$ ./structure_size

Size of the Structure : 36 Bytes
address of num1 in structure a[0] is 134520896
address of num2 in structure  a[0] is 134520900
address of char in structure a[0] is 134520904
address of ptr in structure a[0] is 134520908
address of I element in array abc[5] in structure a[0] is 134520912
address of II element in array abc[5] in structure a[0] is 134520916
address of III element in array abc[5] in structure a[0] is 134520920
address of IV element in array abc[5] in structure a[0] is 134520924
address of V element in array abc[5] in structure a[0] is 134520928
**address of VI element in the 5 element array abc[5] in structure a[0] is 134520932
address of num1 in structure a[1] is 134520932**
kevin@kevin-desktop:~/Documents/programs$ 

3 个答案:

答案 0 :(得分:2)

这就是C的工作原理。我认为这种现象在这个简化的代码中更容易显示:

char string[2][5];              // allocates a block of 10 bytes

string == string[0];            // true
string == &string[0][0];        // true
&string[0][5] == &string[1][0]; // true

答案 1 :(得分:1)

因为您正在做的是未定义的行为,并且当然不需要编译器来检测和报告它。

这是(当然),因为这样做一般来说会非常困难,也因为你可以“动态地”做同样的事情,这使得在编译时或多或少都无法检测到它。

请记住,C没有对数组边界进行运行时检查;你可以索引你想要的任何东西,在大多数情况下编译器将发出代码,尝试进行访问。它可能会被操作系统阻止,但也可能“只是这样做”并对您的生活造成严重破坏。

正如@Adriano所说,欢迎来到C! :)

P.S。指针应打印%p,而不是int s。

答案 2 :(得分:0)

您的abc数组大小为5,表示您有[0],[1],[2],[3],[4]。

你完成了5个元素。但你写了[5]。这是在那个结构之外。

a [2]隐含为(a + 2)其中'a'是地址,a = 134520896,

所以a + 2是134520904

数组中有5个元素,因此数组将获得20个字节。即从134520896到134520915。

134520916是数组a的下一个变量的地址,它不是数组的内存a