在C ++中将向量声明为全局变量

时间:2011-09-26 15:37:56

标签: c++ vector heap

在C ++中将向量声明为全局是一种好习惯吗?

这就是我所做的。

#include <vector>
std::vector<int> vec;

我的程序编译成功,但我不确定这是否会导致运行时 某些情况下的错误。根据我的理解,全局变量的内存将在编译时分配,编译器可以保留此向量可以扩展的有限数量的内存。达到此限制后,正在写入的内容可能会吞噬另一个变量所使用的内存。

请告知。

6 个答案:

答案 0 :(得分:8)

  

我的程序编译成功,但我不确定是否可以   在某些情况下导致运行时错误。

这样做是安全的; vec变量的存储将被静态分配,并且它的默认构造函数将在某个时刻被调用(确切地说,在整个程序的上下文中没有严格定义,因为翻译单元的初始化顺序没有严格定义)。

  

并且编译器可以保留有限数量的内存   矢量可以扩展。达到此限制后,正在编写的内容可以   吃进另一个变量使用的记忆。

向量本身在堆上分配其存储,因此如果将向量实例化为局部变量,则对其扩展不会施加任何限制:您基本上会受到数量的限制你可以在向量需要重新分配其内部存储的时间点连续分配的内存。

所有这些都说,虽然这样做是安全的,但这不一定是好的做法;它属于每个其他全局变量或全局可访问的存储区域,这可能是一个有争议的主题。一般来说,我建议最好避免全局变量作为规则。虽然在某些情况下可能是可以接受的,但全局访问与您控制对变量的访问并强制执行变量及其控制或暗示的状态的能力背道而驰。这可能导致难以维护的系统,因为代码库会扩展,因为这些访问路径没有明确说明。

答案 1 :(得分:4)

  

根据我的理解,全局变量的内存将在编译时分配,编译器可以保留此向量可以扩展的有限内存量。

这是错误的理解。

在编译时,内存不是分配。内存在 startup 程序中分配,然后程序中分配,具体取决于 storage 类型的变量。当程序关闭时,它使用的所有内存都会返回操作系统,无论如何。

  

达到此限制后,正在写入的内容可能会吞噬另一个变量使用的内存。

没有。 std::vector<int>的对象永远不能吃另一个变量使用的内存

现在回到你的主要问题,

  

在C ++中将向量声明为全局是一种好习惯吗?

没有。避免全局变量,无论其类型如何。

答案 2 :(得分:3)

仅在全局变量区域中分配矢量元数据的空间。向量内容仍将动态分配(构造函数和析构函数正常运行全局变量)。

自动矢量变量的情况相同,如:

int main(void)
{
    std::vector<int> v;
    return 0;
}

自动变量可用的堆栈空间有限,但是向量内容不会使用这个空间,只有少数几个指针和计数器。

答案 3 :(得分:3)

嗯,vec是一个全局变量,所以它的内存可能是从数据段分配的。但是,vec内容的内存取决于分配器。默认情况下,我认为内容的内存是从堆中分配的。

答案 4 :(得分:2)

一般来说,全局变量都是不好的做法。正如你所说,它们不会“吞噬”另一个变量的记忆,但是,作为程序员,你很容易搞砸了。例如,程序中的所有内容都可以访问此向量,因此所有内容都可以访问和修改它。您可能会或可能不会想要这个,但更有可能的是,您不希望这样。

对于内存分配,添加到向量的对象仍然在运行时添加(因为它们在编译时不存在!)。内存也从未在编译时分配。您的程序中有签名,可以在运行时分配此内存。想一想......如果程序在编译时分配内存,你真的不能在其他机器上运行它们吗?内存将在您的计算机上分配,但不在其他计算机上分配。因此,必须在运行时分配内存。

答案 5 :(得分:2)

你的程序在编译期间没有分配任何东西 - 我认为你的意思是运行时。

Vector分配它在堆上的内容(vec.size()* sizeof(/ *你持有* /)) - 它在sizeof(std :: vector&lt;&gt;)上保存它所在的位置。全局变量可以存储在任何地方,这取决于实现。