“ new”关键字如何工作?我最近才了解新关键字

时间:2019-03-31 19:26:45

标签: c++

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    vector<string>* Boom = new vector<string>(90);
    Boom->push_back("Boom, son");
    cout << Boom->capacity();

    return 0;
}

我最近刚刚学习了新关键字,同时又学习了向量,所以我决定将两者结合起来。

据我所知,“ new”关键字应该在堆上预留一些内存。

现在,根据上面的代码,我有一些问题:

括号中的90是说要留出多少内存(以字节为单位)还是做其他事情?

字符串的大小为28,那么为什么在我运行代码时得到的值为135?我预计还会得到90,因为我已经预留了90个字节,并且字符串(向量中唯一的元素)只有28个字节。

我是不是对此全都想错了?还是我想的很对,但是我做错了吗?

谢谢。

3 个答案:

答案 0 :(得分:4)

在表达式$query=Address::find()->alias('A') ->select([new Expression('A.*, (6371 * acos(cos(radians("' . $mapSearch->gps_lat . '")) * cos(radians(gps_lat))*cos(radians(gps_long) -radians("' . $mapSearch->gps_long . '")) + sin(radians("' . $mapSearch->gps_lat . '"))*sin(radians(gps_lat)))) AS distance')]) ->join('left join', '{{content_has_address}} CA', 'A.id = CA.address_id') ->join('left join', '{{contest}} C', 'C.id = CA.contest_id') ->join('left join', '{{contest_has_date}} CD', 'C.id = CD.contest_id') ->join('left join', '{{date}} D', 'D.id = CD.date_id') ->where( ['AND', ['=', 'main', 1], ['=', 'C.status', 1], ['>', 'D.start_time', $today] ] ) ->having(['<', 'distance', $mapSearch->distance]) ->orderBy('distance asc'); $dataProvider = new ActiveDataProvider([ 'query' => $query, ]); 中,new T(param)将分配足够的内存来存储正在构造的对象(new)的 type ,在这种情况下为{{ 1}}。括号用于传递给构造函数的参数,因此它将通过T构造对象(这意味着创建一个包含90个字符串的向量)。

您可能会感到困惑,因为vector<string>将分配自己的内存来保存与矢量对象本身分开的元素。因此vector<string>(90)仅分配vector个字节,向量的构造将分配另外new个字节,大致

答案 1 :(得分:3)

  

括号中的90是说要留出多少内存(以字节为单位)还是做其他事情?

在声明中:

vector<string>* Boom = new vector<string>(90);

括号中的90new关键字无关,它只是vector<string>构造函数(位于https://en.cppreference.com/w/cpp/container/vector/vector的构造函数(3)的一个参数):

  
    

3)构造带有默认插入的T个实例的容器。

  

您只需动态分配一个单个向量,并插入90个string对象。

  

字符串的大小为28,那么为什么在我运行代码时得到的值为135?我预计还会得到90,因为我已经预留了90个字节,并且字符串(向量中唯一的元素)只有28个字节。

std::string对象的静态大小取决于实现-在我的https://www.onlinegdb.com/测试中,它只有8个。您没有分配90个字节,而是分配了单个矢量的静态大小(onlineGDB为24个) )。向量类本身会动态地动态分配插入的90个元素的空间(即内部std::vector调用new来分配空间。

此外,capacity()返回必须在向量内部重新分配空间之前可以添加到向量中的对象数。向量中对象的实际数量由length()返回。该容量通常大于长度,因为vector模板会过度分配以避免需要频繁的重新分配/复制。 vector的要求是所有元素在内存中相邻且有序,因此,如果您插入一个新对象并且超出了容量,则向量必须重新分配并将所有现有元素移动到新的内存空间

动态分配向量本身的好处有限,因为向量中的实际对象本身是动态分配的。

  

据我所知,“ new”关键字应该在堆上预留一些内存。

不仅如此-malloc()就是这样做的。 new动态实例化对象。这意味着不仅为对象分配了空间,而且还调用了构造函数。

如此:

new T ;     // allocates a `T` object and calls its default constructor.

new T(a) ;  // allocates a `T` object and passes argument `a` 
            //  to a constructor taking arg of `a`'s type.

new T[n] ;  // allocates n x `T` objects and calls the default 
            // constructor of each.

new T(a)[n] ;  // allocates n x `T` objects and passes `a` to 
               // each constructor.

答案 2 :(得分:0)

new是一个运算符,它将为免费存储中具有类型名称的对象(new)或对象数组(new[])分配内存,并返回适当类型的,是指向对象的非零指针。

在您的示例中,它将为vector<string>(90)分配内存,并将返回该内存上的指针。