在分配给动态数组时,是否在C ++中分配内存?

时间:2014-04-03 19:35:22

标签: c++ arrays pointers memory dynamic

假设在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内存的析构函数?或者我们是否有一个实际指向堆栈内存的动态数组指针?

此外,如果我想保护Foo myData在更改mainData时更改,是否有一种强制Foo构造函数的简单方法要复制吗?理想情况下,myData将是一个简单的数组,而不是指针,但将行double* myData更改为double myData[]似乎无法正常工作,因为在运行时,数组的大小是未知的。

5 个答案:

答案 0 :(得分:3)

此处的参数不是动态数组:

Foo(double data[])

事实上,声明等同于:

Foo(double * data)

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

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

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

  

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

您可以保留数据的副本,但如果在编译时其大小(或至少是上限)未知,则需要指针。我建议std::vector使用裸指针,或至少std::unique_ptr< double[] >

答案 1 :(得分:2)

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

是的,它没有分配额外的内存。

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

答案 4 :(得分:0)

在Foo类实例中的

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