c - 如果有的话,在 C 中如何“接近”其他变量存储的规则是什么?
问题描述
我知道对于一个结构
struct sequences{
int a[3];
int b[3];
} sequence = {{1,2,3},{4,5,6}};
a 和 b 彼此相邻存储,即如果我这样做
int i;
for(i=0; i<6; ++i){
printf("%d", sequence.a[i]);
}
我将得到输出 123456。
我尝试将这两个数组存储在主函数之外,但不在结构中
int a[3] = {1,2,3};
int b[3] = {4,5,6};
当我尝试同样的事情时,
for(i=0; i<6; ++i){
sum = sum + a[i];
}
我得到输出 123045。因此,如果不在结构中,显然不能保证它们彼此相邻存储。
如果我改为在它之后存储一个数组和一个整数,它们似乎总是在内存中彼此之后,即
int a[3] = {1,2,3};
int x = 1000;
和
for(i=0; i<4; ++i){
printf("%d", a[i]);
}
给出 1231000。
我意识到编译器可能会根据我无法控制的一些复杂因素来选择存储变量的位置,但是是否有任何规则可以保证两个变量相互关联的存储位置,就像结构似乎存在一样?
解决方案
C 标准仅保证结构的非位域成员按顺序存储在内存中,元素之间有可选的填充,并且数组的成员按顺序存储而没有填充。
关于结构,C 标准的第 6.7.2.1p15 节规定:
在结构对象中,非位域成员和位域所在的单元的地址按声明顺序递增。一个指向结构对象的指针,经过适当的转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。结构对象中可能有未命名的填充,但不是在其开头。
不能保证将一个不相关的变量放在内存中的另一个变量上。
此外,当你这样做时:
struct sequences{
int a[3];
int b[3];
} sequence = {{1,2,3},{4,5,6}};
...
int i;
for(i=0; i<6; ++i){
printf("%d", sequence.a[i]);
}
您调用未定义的行为是因为您的索引超出了数组成员的末尾a
。b
在这种情况下,实现不需要读取 的元素。在仍然符合标准的同时,最好的办法就是比较&sequence.a[3] == &sequence.b[0]
推荐阅读
- debugging - 问号而不是调试器内存视图中的实际内存内容,这是什么意思?
- r - 如何向该图添加图例(使用 ggplot())?
- javascript - Dictionary .has("key") 不起作用,必须使用 dictionary["key"] != "undefined"
- node.js - 尽管我必须这样做,但使用相同的初始向量进行加密是否被认为是一种不好的做法
- javascript - Firebase 实时数据库查询不适用于更大的数字
- spring - 为什么 Spring 允许实例化具有 Private 构造函数的 bean?
- airflow - BigQueryInsertJobOperator - 缺少必需的参数,但是哪个?
- php - CORS 策略已阻止从源“http://localhost:4200”访问“http://localhost/api/car/create.php”处的 XMLHttpRequest
- android - 在非视图类中访问视图绑定对象?
- javascript - 将两个具有共同变量的比较合并在一起