【问题标题】:Does memory get allocated in C++ when assigning to a dynamic array?分配给动态数组时是否在 C++ 中分配内存?
【发布时间】:2014-05-15 20:26:17
【问题描述】:

假设在 C++ 中,我有以下代码:

class Foo {
private:
    double* myData;
public:
    Foo(double data[]) {
        myData = data;
    }
}

int main() {
    double mainData[] = {1.0};
    Foo myfoo(mainData);
}

据我所知,mainData 在传递给Foo 构造函数时被视为指针,因此myData = data 行仅分配指针地址。所以这里没有分配额外的内存,对吧?但是,Foo 类是否负责提供一个析构函数来释放myData 的内存?还是我们有一个动态数组指针实际上指向栈内存?

另外,如果我想保护FoomyDatamainData 更改时不发生更改,是否有一种简单的方法可以强制Foo 构造函数复制它?理想情况下,myData 将是一个简单的数组,而不是指针,但将行 double* myData 更改为 double myData[] 似乎不起作用,因为数组的大小在运行时之前是未知的。

【问题讨论】:

  • 这类问题会导致 C++ 中出现很多错误。在您的程序中制定明确的数据所有权政策非常重要。如果您希望Foo 拥有其数据,请将myData 替换为std::vector<double> 并根据需要填写。或者 double myData[SIZE] 如果大小在编译时是固定的。

标签: c++ arrays pointers memory dynamic


【解决方案1】:

是的,它不会分配额外的内存。

不,如果没有被告知,析构函数不会对类字段做任何事情。

【讨论】:

    【解决方案2】:

    这里的参数不是动态数组:

    Foo(double data[])
    

    其实声明等价于:

    Foo(double * data)
    

    即使decltype 会告诉你它们是同一个东西,而且这两个签名会因为重载而发生冲突。

    所以,没有分配。您只是传递了一个指向数组第一个元素的指针。

    此外,C++ 会自动复制数组的唯一位置是当它是类的成员时,并且成员不允许使用空括号[] 表示不确定大小的语法。 (或者如果是,则大小已经由类类型完成时,在生成复制构造函数或赋值运算符之前确定。)

    另外,如果我想保护 Foo 的 myData 在 mainData 更改时不发生更改,是否有一种简单的方法可以强制 Foo 构造函数复制它?理想情况下,myData 将是一个简单的数组,而不是指针,但是将 double* myData 行更改为 double myData[] 似乎不起作用,因为数组的大小在运行时之前是未知的。

    您可以保留数据的副本,但如果在编译时它的大小(或至少一个上限)未知,则需要一个指针。我会推荐 std::vector 而不是裸指针,或者至少是 std::unique_ptr< double[] >

    【讨论】:

      【解决方案3】:
      1. 指针只保存一个内存地址,不涉及newdelete,指针与分配或释放无关。因此,您的代码不会调用任何内存分配。
      2. 要删除(动态分配的)数组,您必须执行delete[] foo;
      3. 只有动态分配的对象必须被删除,如果你的类拥有所有权(它管理数组,在销毁时调用 delete)传递一个具有自动存储持续时间的数组是一个非常糟糕的主意。

      【讨论】:

        【解决方案4】:

        在 Foo 类实例中将具有指向由其他类分配/管理的数据的指针,这是非常糟糕的设计。最好的办法是让 Foo 构造函数制作一个副本并将其存储在指针中。然后在析构函数中释放那个。这需要将数组的长度传递给 Foo 构造函数。我希望这会有所帮助。

        【讨论】:

          【解决方案5】:

          在这种情况下,myData 指向堆栈上的一个地址,当函数超出范围时,它将调用 Foo 的析构函数。通常,当您使用关键字 new 分配数组时,数组被描述为动态的。

          至于您的第二个问题,您可能必须向构造函数传递一个指向数组的指针和数组的长度。然后,您需要使用传入的长度动态创建一个双精度数组(由 myData 指向),然后进行复制。

          不要忘记删除析构函数中的内存。

          【讨论】:

            猜你喜欢
            • 2021-02-09
            • 2014-12-09
            • 1970-01-01
            • 1970-01-01
            • 2021-07-17
            • 2013-05-24
            • 2021-04-02
            • 1970-01-01
            相关资源
            最近更新 更多