我是C ++的初学者,我有以下代码:
struct Airline {
string Name;
int diameter;
int weight;
};
Airline* myPlane = new Airline;
我的问题是,当我调用方法new
时,它会分配内存,如果我没记错的话。 PC如何知道要分配多少内存,特别是考虑到那里有字符串类型?
由于
答案 0 :(得分:13)
std::string
对象是固定大小的;它包含一个指向字符实际缓冲区及其长度的指针。 std::string
的定义类似于
class string
{
char *buffer;
size_t nchars;
public:
// interface
};
因此,您的Airline
对象也具有固定大小。
现在,new
不仅分配;它还会初始化您的对象,包括std::string
,这意味着它可能会将char
指针设置为0
,因为该字符串为空。
答案 1 :(得分:3)
您还可以使用sizeof
:
cout << "sizeof(Airline) = " << sizeof(Airline) << endl;
这是因为编译器知道结构中的字段,并将每个结构成员的大小相加。
string
对象与您的结构没有什么不同。它实际上是标准库中的一个类,而不是由编译器处理的特殊类型,如int
或float
。与您的结构一样,string
类包含编译器知道其大小的字段,因此它知道完整结构的大小,并在您使用new
时使用它。
答案 2 :(得分:2)
对new
的调用将分配sizeof(Airline)
,这是保存Airline
类型对象所需的内容。
从字符串管理开始,string
对象保存一些内部数据来管理存储的实际数据的内存,而不是数据本身(除非正在使用小对象优化)。虽然这个想法与存储指向实际字符串的其他人指出的相同,但这不够精确,因为它实现将存储该指针以及保存{{}所需的额外数据。 1}}和size()
(和其他人一样,如引用计数实现中的引用计数)。
答案 3 :(得分:1)
字符串的内存可能在类string
内,也可能不在string
内。可能(可能)类struct Airlane {
String Name {
char *data; // size = 4
size_t size; // size = 4
}
int diameter; // size = 4
int weight; // size = 4
}; // size = 16
将管理自己的内存,只有指向用于存储数据的内存的指针。例如:
class T
请注意,这些不一定是实际尺寸,例如它们。
另请注意,在C ++中(例如,与C不同),对于每个sizeof T
,std::string
是编译时常量,这意味着对象永远不会具有动态大小。这实际上意味着:只要您需要运行时动态大小的数据,就必须有外部(w.r.t.对象)内存区域。这可能意味着使用标准容器,如std::vector
或operator new
,甚至是手动管理的资源。
这反过来意味着,Airline* myPlane = new Airline {
Name = {
data = new char[some-size]
...
}
...
}
不需要递归地知道所有成员的动态大小,而只需要知道最外层类的大小,即你分配的大小。当这个外部类需要更多内存时,它必须自己管理它。一些示例性的p代码:
Airline::Airline() : string(), ... {}
string::string () : data(new char[...] ... {}
内部分配由持有构造函数完成:
operator new
Airline
除了分配一些固定大小的内存作为Airline
的“土壤”(参见第一个p代码),然后是“种子”new
的构造函数时,别无其他它本身必须通过调用字符串构造函数(隐式或显式)来管理其在“土壤”的受限量中的生命周期,它本身会执行另一个{{1}}。
答案 4 :(得分:0)
分配Airline
时,new
会在堆上为两个整数string
及其字段分配足够的空间。
string
在堆栈上的大小始终相同。但是,在内部,string
存储指向字符数组的指针。