存储在全局变量中的数据与存储在堆中的数据之间有什么区别?

时间:2013-05-19 23:23:30

标签: c++ variables heap global

int globalInt = 1; 

int main(){
    int* heapInt = new int(1);
}

globalInt和heapInt有什么区别?我知道heapInt指向的是堆中的内容,我知道globalInt会进入一些全局数据存储,但有什么区别?为什么用一个而不是另一个?

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:4)

全局变量具有静态存储持续时间。这意味着对象从程序启动到结束时都存在。它存在于整个计划期间。

使用new-expression创建的int具有动态存储持续时间。它的生命周期从new-expression开始,到你delete heapInt;时结束。

您可以将这两个存储持续时间视为频谱的两端。全局变量使您对其生命周期的控制最少,因为它始终存在。动态分配的对象可以为您提供最大的控制权,因为您可以在代码中的任何位置创建并销毁它。

值得注意的是,全局变量有一个名称。这使得该对象的所有部分都可以访问该对象,该名称在该范围内。相反,要访问动态分配的对象,需要为其指定一个指针。

全局变量通常被认为是不好的做法,因为它们会为您的程序引入全局状态。也就是说,您可能有一个修改或使用全局变量的函数,而不清楚它是否在其界面中这样做。这意味着该功能可能具有秘密的副作用,导致难以测试的不可预测和不可维护的代码。

另一方面,动态分配的对象通常是必需的,但应谨慎使用。确保正确管理对象的生命周期非常重要。一种方法是使用RAII,其中对象仅在构造函数中动态分配,然后在析构函数中相应地销毁。另一种现代方法是避免完全自己进行内存管理,而是使用智能指针。

答案 1 :(得分:1)

主要区别有两个 - 范围和寿命。

您可以在程序中的任何位置使用globalInt,而只能在heapInt内使用main

全局的生命周期是从程序开始(好,从main之前进入)到结束,而动态分配的生命周期从new开始,当你{{1}时消失它。

答案 2 :(得分:0)

只是烤面条,你也考虑过

int globalInt = 1;
int* globalHeapInt = new int(1);

int main() {
    int* heapInt = new int(1);
}

回答原因部分:在堆中存储任何东西都有指针的开销 - 4或8个字节,具体取决于你要构建的位数。

像plainInt这样的普通数据类型的全局值被写出到可执行文件的“数据段”,并且当操作系统启动应用程序时,它们被加载,硬连接到进程中。

globalHeapInt将加载NULL值,然后在编译器提供的一些秘密引导“pre-main”代码中,程序将不得不执行:

globalHeapInt = malloc(sizeof(int));
*globalHeapInt = 1;

在64位系统上,您现在使用(至少)12个字节来存储4个字节的值。

“heapInt”执行类似的操作,但指针存储在堆栈或寄存器中。

为什么要使用全局值?当你拥有有限的,已知数量的数据时,将它们放在简单的全局变量中是有意义的。

所以主要是堆用于动态存储 - 当你事先不知道是否还需要多少时。例如,假设一个程序将一系列书籍作为命令参数:

// reserve memory for upto 1000 Books.
Book globalBooks[1000];

// or use the heap when we know how many we need.
int main(int argc, const char* argv[])
{
    int numBooks = argc;
    if ( numBooks < 1 ) {
       printf("Screw you and your empty book list.\n");
       exit(1);
    }
    Books* heapBooks = new Books(numBooks);
    ...
}

第一种形式只能处理1000本书,但总有1000本书的记忆。第二种形式可以处理任意数量的书籍,直到该过程可用的最大内存量。