【问题标题】:Sharing an array between two structs在两个结构之间共享一个数组
【发布时间】:2020-05-14 02:03:08
【问题描述】:

之前有人问过类似的问题,但我有一些更深入的问题。

假设我有结构

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.因为 C++ 不是这样工作的。数组在 C++ 中并不真正存在。它们是每个人想象的虚构。他们只是绝地的头脑戏法。 2. 这就是指针的用途。使用对 C++ 中对象的正确用法和范围有完整、透彻理解的指针。
  • 如果你希望两个结构都指向一个数组(可能相同),它们应该有一个指向数组的字段。
  • 另外,这个问题是关于 c 还是 c++ 的?你已经用两者标记了它,但它们是不同的语言。
  • 如果你真的用 c++ 编码,你可以使用 std::shared_ptr

标签: c++ arrays struct


【解决方案1】:
  1. 为什么我可以轻松地...通过简单地分配指针

因为指针是可赋值的。

但我不能用于数组?

因为数组是不可赋值的。

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

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

但我不能用于数组?

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

为什么他们的待遇不同?

指针的特殊之处在于它们如何通过间接实现数据共享。好的,还有另一种形式的间接(引用),所以指针在这方面并不是很独特。

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

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

简而言之:速度。


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

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

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

如果我尝试通过投射发挥创意,我会收到错误消息

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

【讨论】:

    【解决方案2】:

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

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

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

    所以当然两个threads'fdtable 子对象不能引用同一个数组。 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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 2015-07-30
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多