在两个结构之间共享数组

Sharing an array between two structs

本文关键字:结构 之间 共享 数组 两个      更新时间:2023-10-16

之前也问过类似的问题,但我有几个更深入的问题。

假设我有结构

struct thread {
pagetable* pt;
vnode* fdtable[64];
};

我有该结构的现有实例,以及一个名为p的全新实例。我希望pfdtable元素指向与旧结构相同的fdtable数组,以便对一个结构中的数组的更改将反映在另一个结构的数组中。但是,当我这样做时p->fdtable = this->fdtable;我收到错误消息invalid array assignment.如果我尝试在选角方面发挥创意,我会收到错误消息incompatible types in assignment of 'vnode**' to 'vnode* [64]'

无论我尝试什么,编译器都非常坚持阻止我正在尝试做的事情。在网上做了一些研究后,似乎我试图做的事情是不可能的。

我的问题有几个部分:

  1. 为什么我可以通过简单地分配指针来轻松共享其他数据类型p->pt = this->pt;而我不能为数组分配?这背后的设计决策的原因是什么?既然数组的大小不能改变,为什么对待它们的方式不同?
  2. 在结构之间完成共享数组的最简单方法是什么?现在我的计划是创建一种包含所有共享信息的新型结构,然后简单地使两个结构都指向这个共享结构。但是,我想知道是否有更好的方法。
  1. 为什么我可以轻松...通过简单地分配指针

因为指针是可分配的。

但我不能为数组?

因为数组是不可分配的。

为什么我可以轻松共享...通过简单地分配指针

因为指针是间接的一种形式。

但我不能为数组?

因为数组不是一种间接形式。

为什么对待他们不同?

指针在如何通过间接实现数据共享方面非常特殊。好的,还有另一种形式的间接寻址(引用(,因此指针在这方面并不是很独特。

这背后的设计决策的原因是什么?

在具有显式内存管理而不是垃圾回收的语言中,没有显式区分值类型和引用/指针的隐式间接寻址根本不可能。垃圾回收由于其运行时开销而被认为是不可取的。间接寻址本身也有一些开销。

简而言之:速度。


  1. 结构之间完成共享数组的最简单方法是什么?

这可以通过间接实现:不要将数组存储在对象中,而是存储指向数组的指针。然后,多个实例可以指向同一个数组。

但请注意,确保指向数组的生存期比指针的生存期长会很棘手。解决此问题的最简单(尽管不一定是最佳(方法是通过使用共享指针来使用数组的共享所有权。

如果我尝试在选角方面发挥创意,则会收到错误消息

听起来你在那里躲过了一颗子弹。感谢类型系统保存您的程序。

与您可能听到的相反,C++中的数组不是指针。 数组可以隐式转换为指向其第一个元素的指针,但它本身不是指针。

要了解为什么这不起作用,首先考虑thread对象在内存中的样子。 它将布局如下:

pagetable
+-------+
thread         +->+       |
+------------+ |  +-------+
| pt         +-+  vnode
+------------+    +-------+
| fdtable[0] +--->+       |
+------------+    +-------+
| fdtable[1] +-+  vnode
+------------+ |  +-------+
|            | +->+       |
| ...        |    +-------+
|            |    vnode
+------------+    +-------+
| fdtable[63]+--->+       |
+------------+    +-------+

因此,当然两个threadfdtable子对象不能引用同一个数组。fdtable没有引用任何东西;fdtable数组。

你可以将一个threadfdtable的每个元素复制到另一个元素中,以便两个thread对象都引用相同的vnode对象,但是简单的赋值是行不通的,因为数组在C++中的语义(有点愚蠢(。 您必须遍历数组并单独复制其元素:

for (std::size_t i = 0; i < 64; ++i) {
p->fdtable[i] = this->fdtable[i];
}

或使用类似std::copy

std::copy(this->fdtable, this->fdtable + 64, p->fdtable);