我正在尝试理解以下代码:
struct mys {
double d[128];
};
void my_func(int iters) {
int i;
struct mys *ptr = malloc(iters *sizeof(struct mys));
for(i = 0; i < iters; i++) {
ptr[i].d[0] = (double)i;
}
free(ptr);
}
我所知道的:
mys
的大小为8 * 128
(double
的大小为8
,它是128
的双精度数组)
*ptr
的大小为iters * (8 * 128)
这是怎么回事:
ptr[i].d[0] = (double)i;
?
我所知道的:
// ptr->d is the address of the first part of d
// same as (*ptr).d
// BECAUSE d IS A STRUCT
// ptr->d[i] is the actual value. so, 0.0000
// same as (*ptr).d[i]
谢谢。
ptr[i]
是索引i
的值,因此从0.0000
开始。
d
未初始化,仅是struct
成员的名称。我们怎么能d
在这里?
我的想法:
*ptr
是多个(iters
)结构。
因此,ptr[0]
是第一个struct
,ptr[1]
是第二个struct
,依此类推。
ptr[i].d
访问第i
个结构的d
数组。
ptr[i].d[0]
访问d数组的第一个索引。因此,上面的行将该数字设置为double(i)
。
因此,这实际上仅将每个结构的第一个元素设置为0
。我说的对吗?
但是当iters
是2
时,我尝试:
for(int i = 0; i < iters; i++) {
printf("%p\n", ptr[200].d);
}
它仍然打印地址。为什么会这样?
答案 0 :(得分:2)
这是怎么回事:
ptr[i].d[0] = (double)i;
?
此:
struct mys *ptr = malloc(iters *sizeof(struct mys));
为称为ptr
的结构数组分配内存。
这行代码:
ptr[i].d[0] = (double)i;
将i
分配给数组d
中第i
个结构的数组ptr
的第一个数组i
。
double
被强制转换为d
,因为i
是双精度数组,并且int
被声明为iters
。
当
for(int i = 0; i < iters; i++) { printf("%p\n", ptr[200].d); }
为2时,我尝试:ptr
仍显示地址。这是为什么?因为import {normalize, Schema, arrayOf} from 'normalizr'; var data = [ { "id": 1, "name": "О компании", "children": [ { "id": 5, "name": "Руководство", "children": [ { "id": 6, "name": "Генеральный директор", "children": [ { "id": 20, "name": "Зам гендира" }, { "id": 8, "name": "Секретарша" } ] }, { "id": 7, "name": "Главный бухгалтер", "children": [ { "id": 21, "name": "Зам главбуха" } ] } ] } ] }, { "id": 2, "name": "Вакансии", "children": [ { "id": 9, "name": "Фронтенд-разработчик (JS)" }, { "id": 10, "name": "Бэкэнд-разработчик (Java)" }, { "id": 11, "name": "Оператор ЭВМ" } ] } ];
只有2个结构,所以它不应该超出范围吗?
这肯定超出范围,因为数组的索引为0。
但是,该尝试会调用 Undefined Behavior (UB),这意味着您不知道代码的行为方式。例如,在您的计算机上它会打印一个地址,在我的计算机上它可能会导致分段错误,等等。
答案 1 :(得分:0)
因此,这实际上仅将每个结构的第一个元素设置为0。对吗?
它将复制到类型i
的索引double
复制到每个结构的第一个元素中。否则你是对的。
关于表达式ptr[200].d
,这与&(ptr[200])
相同,因为数组d[]
是mys
对象的唯一元素。由于double
的宽度为8个字节,因此每个mys
对象占用的空间为(8个字节)(128)= 1 kiB。因此,&(ptr[200]) == ptr + 200*1024
。最后一个地址是*ptr
开头之后200 kiB的地址。地址是否有意义取决于其中是否存储了有意义的内容。