【问题标题】:C++: struct and new keywordC++:结构和新关键字
【发布时间】:2012-03-05 15:49:25
【问题描述】:

我是 C++ 的初学者,我有以下代码:

struct Airline {
    string Name;
    int diameter;
    int weight;
};

Airline* myPlane = new Airline;

我的问题是,如果我没记错的话,当我调用 new 方法时,它会分配内存。 PC如何知道要分配多少内存,尤其是考虑到那里有一个字符串类型?

谢谢

【问题讨论】:

  • 我的猜测,不知道 C++,是它只存储一个指向字符串的指针,其实际内容在堆中的某个地方。

标签: c++ memory-management struct new-operator


【解决方案1】:

std::string 对象是固定大小的;它包含一个指向实际字符缓冲区的指针及其长度。 std::string 的定义类似于

class string
{
    char *buffer;
    size_t nchars;

  public:
    // interface
};

因此您的Airline 对象也具有固定大小。

现在,new 不仅分配;它还会初始化您的对象,包括std::string,这意味着它可能将char 指针设置为0,因为字符串为空。

【讨论】:

    【解决方案2】:

    您还可以通过sizeof 获取结构的大小:

    cout << "sizeof(Airline) = " << sizeof(Airline) << endl;
    

    这是因为编译器知道结构内的字段,并将每个结构成员的大小相加。

    string 对象与您的结构没有什么不同。它实际上是标准库中的一个类,而不是像intfloat 这样由编译器处理的特殊类型。与您的结构一样,string 类包含编译器知道大小的字段,因此它知道您的完整结构的大小并在您使用 new 时使用它。

    【讨论】:

      【解决方案3】:

      new 的调用将分配sizeof(Airline),这是保存Airline 类型的对象所需要的。

      对于字符串的管理,string 对象持有一些内部数据来管理实际存储数据的内存,但不包括数据本身(除非正在使用小对象优化)。虽然这个想法与其他人指出的相同,存储一个指向实际字符串的指针,但这不够精确,因为它的实现将存储该指针以及保存@987654325所需的额外数据@ 和 capacity()(以及其他,如引用计数实现中的引用计数)。

      【讨论】:

        【解决方案4】:

        字符串的内存可能在也可能不在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
        

        请注意,这些不一定是实际尺寸,它们只是举例。

        还请注意,在 C++ 中(例如,与 C 不同),对于每个 class Tsizeof T 是一个编译时间常数,这意味着对象永远不会具有动态大小。这实际上意味着:只要您需要运行时动态大小的数据,就必须有外部(w.r.t. 对象)内存区域。这可能意味着使用std::stringstd::vector 等标准容器,甚至是手动管理的资源。

        这反过来意味着,operator new 不需要递归地知道所有成员的动态大小,而只需要知道最外层类的大小,即您分配的那个。当这个外部类需要更多内存时,它必须自己管理它。一些示例性 p 代码:

        Airline* myPlane = new Airline {
            Name = {
                data = new char[some-size]
                ...
            }
            ...
        }
        

        内部分配由持有构造函数完成:

        Airline::Airline() : string(), ... {}
        string::string () : data(new char[...] ... {}
        

        operator new 除了分配一些固定大小的内存作为Airline 的“土壤”(参见第一个 p 代码),然后“种子”Airlines 构造函数,它本身必须管理其通过调用字符串构造函数(隐式或显式),在有限的“土壤”体积中的生命周期,该构造函数本身执行另一个 new

        【讨论】:

          【解决方案5】:

          当您分配Airline 时,new 将在堆上为两个整数分配足够的空间,string 及其字段。

          string 在堆栈上的大小将始终相同。但是,在内部,string 存储了一个指向字符数组的指针。

          【讨论】:

          • 您可能想要添加 where new 分配以及 new 的返回与该位置的关系。
          猜你喜欢
          • 2019-01-23
          • 2016-04-05
          • 2023-01-27
          • 1970-01-01
          • 2016-06-21
          • 2012-10-29
          • 1970-01-01
          • 2017-08-10
          • 1970-01-01
          相关资源
          最近更新 更多