#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个字节。
我是否认为这一切都是错的,或者我在思考,但我做错了?
谢谢。
括号中的90是否表示以字节为单位留出多少内存,还是做其他事情?
在声明中:
vector<string>* Boom = new vector<string>(90);
括号中的90
与new
关键字无关,它只是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.
在表达式new T(param)
中,new
将分配足够的内存来存储正在构造的对象类型(T
),在本例中为vector<string>
。括号用于传递给构造函数的参数,因此它将通过vector<string>(90)
构造对象(这意味着创建一个包含90个字符串的向量)。
您可能会感到困惑,因为vector
将分配自己的内存来保存元素与矢量对象本身分开。所以new
只分配sizeof(vector<string>)
字节,矢量的构造将大致分配另一个90 * sizeof(string)
字节。
new
是一个运算符,它将为自由存储中的类型名称的对象(new
)或对象数组(new[]
)分配内存,并返回一个指向该对象的适当类型的非零指针。
在你的例子中,它将为vector<string>(90)
分配内存,它将返回指向该内存的指针。