【问题标题】:Dynamically allocated structure array with an dynamically allocated structure array element具有动态分配结构数组元素的动态分配结构数组
【发布时间】:2019-07-19 18:29:15
【问题描述】:

请考虑以下代码:

struct X
{
   int x1;
   int x2;
};

struct Y
{
   int y1;
   struct X *x;
};

现在我动态分配内存如下:

struct Y *y = new Y[N];

对于这个结构体数组的每个元素,我也在为y[i].x分配内存,如下-

y[i].x = new X[M];

在这种情况下,在知道y[i].x的实际内存大小之前,系统如何为y分配内存。

在这种情况下,我遇到了分段错误。有什么好的方法来动态分配内存吗?如果我需要重新分配内存(动态增加数组大小)怎么办?

【问题讨论】:

  • x的大小总是一样的,是一个指针
  • 你想使用std::vector
  • 每当您想到“动态数组”时,您的下一个想法几乎应该总是std::vector
  • @someprogrammerdude 人类就像向量。我们有时会扩张,但收缩是困难的。
  • vector 不仅仅是一个花哨的动态数组。请注意,您的 struct Y 以多种方式损坏。它可以被复制,但如果你这样做了,就会发生坏事。它可以与自动存储一起使用,但是当它超出范围时会泄漏内存。获得正确的动态内存分配需要更多的时间,你不想每次都重写,因为其他人已经为你做了:std::vector

标签: c++ structure dynamic-memory-allocation


【解决方案1】:

在这种情况下,系统如何在知道y[i].x的实际内存大小之前为y分配内存。

哦,但它确实知道y[i].x 的大小。该成员的类型是struct X*,它是一个指针。指针的大小因架构而异,但通常是 32 位 64 位。不管X 是什么(很少有像函数指针这样的边缘情况)。

换句话说,X不是Y 的一部分。实际上Y 有一个指针指向一块被(可能是多个)X 占用的内存。

这就像有一个地址。你可以把它写在一张小纸上并保存下来。每个人都知道纸张的大小。无论有多少(以及有多大)房屋占据实际位置。

您的分段错误与所有这些无关。很可能你已经越过了一些界限。但是没有实际代码就很难判断。

【讨论】:

    【解决方案2】:

    在这种情况下,在知道y[i].x的实际内存大小之前,系统如何为y分配内存。

    编译器知道指针的大小,如当前声明的x
    当您尝试取消引用 y[i].x 时,最有可能发生分段错误,因为您从未正确分配它应该指向的内存。

    有没有什么好办法动态分配内存?

    是的,有。您应该使用std::vector 让它为您处理手动内存管理的所有障碍和陷阱:

    struct X
    {
       int x1;
       int x2;
    };
    
    struct Y
    {
       int y1;
       std::vector<X> x;
    };
    
    std::vector<Y> y(N);
    y[i].x.resize(M);
    

    如果我需要重新分配内存(动态增加数组大小)怎么办?

    这也将由std::vector 类管理。

    【讨论】:

      【解决方案3】:

      y[i].x 始终是一个在每个系统上都有固定大小的指针。 (主要是 32/64 位)。 这就是系统知道为每个 Y 实例分配多少内存的原因。

      【讨论】:

        【解决方案4】:

        在这种情况下,系统如何在知道y[i].x的实际内存大小之前为y分配内存

        Yx的类型是指向X的指针,所以size就是指针的大小,分配Y时指向的内存块不相关

        有没有什么好办法动态分配内存?如果我需要重新分配内存(动态增加数组大小)怎么办?

        显然你需要一个 std::vector&lt;X&gt; 而不是指向 X 的指针,你在 C++ 中,而不是在 C 中

        【讨论】:

        • C 就不用说了。C++ 并不是更好的 C。C 是一种不同的语言,针对不同的问题有不同的解决方案
        • @user463035818 我从来没有说过 C++ 比 C 更好,你在哪里读到的?我只是说OP使用类似于我们在C中所做的方式,使用C++中存在但C中不存在的vector更实用。你错误地解释了我的句子;-)跨度>
        • 我没有逐字引用你,但 C 没有向量这一事实无关紧要,它传达的唯一信息是 C++ 会更好,因为它有向量。是的,这就是我认为您的句子可以解释的方式。顺便说一句,没有理由感到被冒犯,我只是想告诉你我为什么不投票会很好;)
        • @user463035818 “C 没有向量是无关紧要的”:你再次错误地解释,我从来没有说过“C 没有向量”,我说“C++ 有向量”。好奇怪……
        • 你可以坚持我的解释是错误的,或者你可以考虑我的观点。不是很奇怪,但有点难过……
        猜你喜欢
        • 2021-10-30
        • 2017-03-30
        • 1970-01-01
        • 2020-03-06
        • 2012-03-25
        • 2011-12-13
        相关资源
        最近更新 更多