C 结构成员-地址重叠

C 结构成员-地址重叠,c,arrays,memory-management,structure,C,Arrays,Memory Management,Structure,在这个程序中,我声明了一个结构和几个成员,并且使用了两个元素的数组作为这个特定结构的实例。我在这个结构中使用了一个5元素数组。一个特别的地方是,在main函数中,当我试图获取5元素数组中不存在的第6个元素的地址时,我得到了下一个结构的第一个成员整数的地址。为什么我尝试访问一个不存在的数组元素时没有显示错误,为什么两个成员具有相同的地址 #include<stdio.h> struct {int num1,num2; char s1; int *ptr; int abc[5]; }a

在这个程序中,我声明了一个结构和几个成员,并且使用了两个元素的数组作为这个特定结构的实例。我在这个结构中使用了一个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$ 
#包括
结构{intnum1,num2;字符s1;int*ptr;intabc[5];}a[2];
void main(){
int开始,最后;
start=&a[1]。num1;
last=&a[0]。num1;
printf(“\n结构大小:%d字节”,最后开始);
printf(“\n结构a[0]中num1的地址为%d”,&a[0].num1);
printf(“\n结构a[0]中num2的地址为%d”,&a[0].num2);
printf(“\n结构a[0]中的字符地址为%d”,&a[0].s1);
printf(“\n结构a[0]中的ptr地址为%d”,&a[0].ptr);
printf(“\n结构a[0]中数组abc[5]中I元素的地址为%d”,&a[0].abc[0]);
printf(“\n结构a[0]中数组abc[5]中II元素的地址为%d”,&a[0].abc[1]);
printf(“\n结构a[0]中数组abc[5]中III元素的地址为%d”,&a[0].abc[2]);
printf(“\n结构a[0]中数组abc[5]中IV元素的地址为%d”,&a[0].abc[3]);
printf(“\n结构a[0]中数组abc[5]中V元素的地址为%d”,&a[0].abc[4]);
**printf(“\n结构a[0]中5元素数组abc[5]中VI元素的地址为%d”,&a[0].abc[5]);
printf(“\n结构a[1]中num1的地址为%d”,&a[1].num1)**
printf(“\n”);
}
kevin@kevin-桌面:~/Documents/programs$gcc--版本
gcc(Ubuntu 4.4.3-4ubuntu5.1)4.4.3
版权所有(C)2009免费软件基金会。
这是自由软件;有关复制条件,请参见源。没有
担保甚至不是为了适销性或适合某一特定目的。
kevin@kevin-桌面:~/Documents/programs$gcc structure\u size.c-o structure\u size
结构_size.c:在函数“main”中:
structure_size.c:15:警告:赋值从指针生成整数而不进行强制转换
结构_size.c:17:警告:赋值从指针生成整数而不进行强制转换
结构\u size.c:21:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:23:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构_size.c:25:警告:格式“%d”要求类型为“int”,但参数2的类型为“char*”
结构\u size.c:27:警告:格式“%d”要求类型为“int”,但参数2的类型为“int**”
结构\u size.c:29:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:31:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:33:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:35:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:37:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:39:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
结构\u size.c:41:警告:格式“%d”要求类型为“int”,但参数2的类型为“int*”
kevin@kevin-桌面:~/Documents/programs$。/structure\u大小
结构的大小:36字节
结构a[0]中num1的地址为134520896
结构a[0]中num2的地址为134520900
结构a[0]中的字符地址为134520904
结构a[0]中的ptr地址为134520908
结构a[0]中数组abc[5]中I元素的地址为134520912
结构a[0]中数组abc[5]中II元素的地址为134520916
结构a[0]中数组abc[5]中III元素的地址为134520920
结构a[0]中数组abc[5]中IV元素的地址为134520924
结构a[0]中数组abc[5]中V元素的地址为134520928
**结构a[0]中5元素数组abc[5]中VI元素的地址为134520932
结构a[1]中num1的地址为134520932**
kevin@kevin-桌面:~/Documents/programs$

因为您所做的是未定义的行为,编译器当然不需要检测和报告它

这(当然)是因为这样做通常非常困难,而且还因为您可以“动态地”做同样的事情,这使得在编译时或多或少不可能检测到

记住,C没有数组边界的运行时检查;您可以索引任何您想要的内容,在大多数情况下,编译器将发出代码并尝试进行访问。它可能会被操作系统阻止,但它也可能“就这么做”,给你的生活带来一些混乱

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


p.S.指针应该用
%p
打印,它们不是
int
S.

这是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

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

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

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

所以a+2等于134520904

数组中有5个元素,所以数组将获得20个字节。i、 e.从134520896至134520915


134520916是数组a的下一个变量的地址,它不是数组a的内存,因为您在C中(在这种情况下,第二个结构在第一个结构之后分配到内存中)。欢迎。如果索引数组超出范围,则表示行为未定义。感谢您的解释。