哪个(在哪个内存段中)是用C ++存储的对象(类)?

时间:2016-07-21 20:19:41

标签: c++ memory-segmentation

我们以下面的课程为例

class Shape{
    public:
      Circle (int x): number(x){}
      virtual area () {return x**2;}

    private:
      int number;
}

在main中我们创建对象

int main(){
    Shape *foo = new Shape(8);
    Shape *bar = new Shape(65);
    Shape &obj1 = *foo, &obj2 = *bar;
}

我相信对象1和2存储在堆中。这是为什么? 作为一个附带问题。关键字virtual,或/和对象的定义方式(例如obj1 = * foo)会影响其在内存中的定位吗?

1 个答案:

答案 0 :(得分:0)

有(广义上)两种类型的对象W.R.T.他们的记忆管理:

  1. 在编译期间可以完全构造对象
  2. 对象只能使用在程序运行之后才可用的某些信息完全构建
  3. 例如,任何constexpr类型对象都可以在编译期间进行完全评估和构造,因此可以作为优化放入内存数据段(从纯粹主义的角度看它是有效的,但远从最优开始,在运行时构造这样的对象。但这会浪费CPU周期并使初始化/启动时间更长。)

    以下是此类对象的一些示例:

    const char * const helloWorld = "Hello, world!";
    struct TSilly{
        TSilly(int _i = 0) : i(_i) {}
        int i;
    };
    const TSilly silly1;
    const TSilly silly2(42);
    TSilly silly3;   // doesn't have to be constexpr to qualify for static allocation.
                     // This one you can declare as /*extern TSilly silly3;*/ in
                     // header file and access from other compilation units
    static TSilly silly4;  // can be local to compilation unit, too
    
    int main()
    {
        return 0;
    }
    

    所有其他对象都必须等到构建运行时。

    此类对象的示例:

    const char * exeName1; // statically allocated by compiler
    
    int main(int argc, char **argv)
    {
        exeName1 = argv[0];  // now points to a string
    
        // buffer is allocated in free storage (heap) bu variable itself is on stack
        char * exeName2 = new char[strlen(argv[0] + 1];
        strcpy(exeName2, argv[0]); // now contains a COPY of a string
    
        char exeName3[1024];  // likely allocated on stack, be careful with that as stack space is limited
        strncpy(exeName3, argv[0], 1024); // will COPY at most 1023 characters from a string
    
        delete [] exeName2;  // don't forget to clean up
        // exename3 will be auto-cleaned when we exit the function
    
        return 0;
    }
    

    正如您所看到的,C ++中的对象将根据其生命周期被放入数据段或空闲存储(堆)中。

    只保证将动态分配的对象放入免费存储空间。我不认为规范对静态分配的对象使用数据段做出了任何承诺 - 编译器需要执行和利用该优化。

    有关详情,请参阅Google“C ++存储类”。

    您可能需要查看大量高级内存管理主题。与此讨论最相关的可能是就地构造函数,它允许您在可执行文件的数据段中分配的内存中构建运行时对象。

相关问题