在 C++ 中将向量声明为全局变量
在 C++ 中将向量声明为全局是一个好习惯吗?
这就是我所做的。
#include <vector>
std::vector<int> vec;
我的程序编译成功,但我不确定这是否会导致运行时 某些情况下会出现错误。根据我的理解,全局变量的内存将在编译时分配,并且编译器可能会保留该向量可以扩展的有限内存量。达到此限制后,正在写入的内容可能会占用另一个变量使用的内存。
请指教。
Is it a good practice to declare a vector as global in C++?
This is what I did.
#include <vector>
std::vector<int> vec;
My program compiles successfully, but I am not sure whether this could lead to a runtime
error under certain circumstances. According to my understanding, the memory for a global variable will be allocated at compile time, and the compiler may reserve a limited amount of memory to which this vector can expand. Upon hitting this limit, what is being written can eat into the memory used by another variable.
Please advise.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这样做是安全的;
vec
变量的存储将被静态分配,并且它的默认构造函数将在某个时刻被调用(确切地说,在整个程序的上下文中没有严格定义,因为跨翻译单元的初始化顺序是没有严格定义)。向量本身在堆上分配其存储空间,因此对其扩展不会施加任何限制,如果将向量实例化为局部变量,情况会有所不同:基本上会受到可以连续使用的内存量的限制在向量需要重新分配其内部存储的时间点分配。
综上所述,虽然这样做是安全的,但这不一定是好的做法。它属于所有其他全局变量或全局可访问存储位的领域,这可能是一个有争议的话题。一般来说,我建议最好避免全局变量。虽然在某些情况下可能是可以接受的,但全局访问与您控制对变量的访问以及对其强制不变量及其控制或暗示的状态的能力背道而驰。随着代码库的扩展,这可能会导致系统难以维护,因为这些访问路径没有明确说明。
This is safe to do; the storage for the
vec
variable will be allocated statically and its default constructor will be called at some point (exactly when within the context of your entire program is not strictly defined, as order of initialization across translation units is not strictly defined).The vector itself allocates its storage on the heap, so there will be no limitations imposed upon its expansion that would be different if you instantiated the vector as a local variable: you're basically going to be limited by the amount of memory you can contiguously allocate at the points in time the vector needs to reallocate its internal storage.
All of that said, while this is safe to do so, it isn't necessarily good practice; it falls into the domain of every other global variable or globally-accessible bit of storage, which can be a bit of a contentious subject. Generally, I would advise that it is preferable to avoid global variable as a rule. While it may be acceptable in some cases, the global access runs counter to your ability to control the access to the variable and enforce invariants on it and the state it controls or implies. This can lead to difficult-to-maintain systems as a codebase scales because those access paths are not clearly spelled out.
这是错误的理解。
编译时未分配内存。内存在程序启动时分配,然后在程序期间分配,具体取决于变量的存储类型。当程序关闭时,无论如何,它使用的所有内存都会返回操作系统。
不可以。
std::vector
对象永远不能占用另一个变量使用的内存。现在回到你的主要问题,
不。避免全局变量,无论其类型如何。
This is wrong understanding.
Memory is not allocated at compile time. Memory is allocated at the program startup, and then during the program, depending on the storage types of variables. And when the program shutdowns, all the memory used by it returns to the OS, no matter what.
No. An object of
std::vector<int>
can never eat memory used by another variable(s).Now coming back to your main question,
No. Avoid global variables, irrespective of their types.
只有矢量元数据的空间将被分配在全局变量的区域中。向量内容仍将动态分配(全局变量的构造函数和析构函数正常运行)。
对于自动向量变量来说也是同样的情况,例如:
可用于自动变量的堆栈空间是有限的,但是向量内容不会使用这个空间,只有少量的指针和计数器。
Only the space for the vector metadata will be allocated in the area for global variables. The vector contents will still be dynamically allocated (constructors and destructors run normally for global variables).
It's the same situation for an automatic vector variable, like:
There's a limit to the stack space available for automatic variables, but the vector contents won't use this space, only a handful of pointers and counters.
一般来说,全局变量是不好的做法。正如您所说,它们不会“吃掉”另一个变量的内存,但是,作为程序员,您很容易搞砸一些事情。例如,程序中的所有内容都可以访问该向量,因此所有内容都可以访问和修改它。你可能想要也可能不想要这个,但很可能你不想要这个。
至于内存分配,添加到向量中的对象仍然会在运行时添加(因为它们在编译时不存在!)。编译时也不会分配内存。您的程序中具有在运行时分配此内存的签名。想想看......如果程序在编译时分配内存,您将无法在其他机器上运行它们,不是吗?内存将在您的计算机上分配,但不会在其他计算机上分配。因此,必须在运行时分配内存。
Global variables in general are bad practice. They won't "eat" into memory of another variable as you say, however, it's very easy for you as the programmer to screw something up. For example, everything in the program has access to this vector and so everything can access and modify it. You may or may not want this, but more than likely, you don't want this.
As for memory allocation, objects added to the vector are still added on runtime (because they don't exist on compile time!). Memory is also never allocated at compile time. Your program has the signature in it to allocate this memory at RUN time. Think about that...if the program allocated memory at compile time, you wouldn't really be able to run them on other machines would you? The memory would be allocated on YOUR machine, but not on other machines. Hence, memory must be allocated on run time.
你的程序在编译时不会分配任何东西 - 我认为你的意思是运行时。
Vector 分配它在堆上保存的内容 (vec.size() * sizeof(/* 你保存的内容*/)) - 它在分配的位置保存 sizeof(std::vector<>) 。全局变量可以存储在任何地方,这取决于实现。
Your program doesn't allocate anything during compile-time - I think you mean run-time.
Vector allocates what it holds on the heap (vec.size() * sizeof(/* what you are holding*/)) - it holds sizeof(std::vector<>) on where it is allocated. Global variables may be stored anywhere, it depends on the implementation.
好吧,vec 是一个全局变量,所以它的内存大概是从数据段分配的。但是,vec 内容的内存取决于分配器。默认情况下,我认为内容的内存是从堆中分配的。
Well, vec is a global variable, so the memory for it is presumably allocated from the data segment. However, the memory for the contents of vec depends on the allocator. By default, I think that the memory for the contents is allocated from the heap.