C ++中的静态全局变量

时间:2013-01-16 01:08:59

标签: c++ variables pointers static global

我想通过malloc方法创建一个整数数组。我希望这个数组是全局的,可以在我的程序中的任何地方使用。我把代码放在一个看起来像这样的头文件中:

static int *pieces;

然后我有一个功能,用我想要的数字填充它。该函数位于命名空间中,命名空间在其自己的.cpp文件中实现。但是,我将头文件导入main.c并从创建数组的命名空间调用该函数,如:

pieces = malloc(sizeof(int) * 128);

但是当我尝试在main中访问数组中的数字时(在调用创建我的数组的函数之后),它崩溃并说没有初始化那些碎片。但是在我拥有的功能中,我可以创建它并操纵它中的数字就好了。我的印象是,通过使片段成为静态变量,只要某个函数在任何地方发生变化(或设置它),那么这将影响变量在任何地方的使用。基本上我想说的是为什么在主要部分中出现未设置的部分,即使我将它设置在我调用的函数中?

4 个答案:

答案 0 :(得分:58)

Static是一个含有多种含义的关键字,在这种特殊情况下,它意味着不是全局(释义)

这意味着每个 .cpp文件都有自己的副本。因此,当您在main.cpp初始化时,仅在main.cpp 中初始化。其他文件仍然没有初始化。

要解决此问题,首先要删除关键字static。这将导致“多个定义问题”。要解决此问题,您应该在.cpp文件中定义变量,并在extern中将其声明为头文件。


编辑:你只是为它分配内存,不算作初始化。分配后需要将内存初始化为0.

您可以使用new int[128]()代替更详细的malloc语法,这也是perform initialization吗?或者你可以采取简单的道路(这就是它的用途)并使用std::vector

答案 1 :(得分:16)

关键是:

static int *pieces;

你说你把它放在标题中。这不是导出符号的方法。任何包含标头的文件都将获得一个名为pieces的未初始化指针的静态版本。

相反,你把它放在标题中:

extern int *pieces;

extern int init_pieces();

在源文件中,您可以这样做:

static const size_t num_pieces = 128;

int *pieces = 0;

int init_pieces()
{
    pieces = malloc( num_pieces * sizeof(int) );
    return pieces != NULL;
}

现在,当您包含标头时,您的源文件将知道从其他位置获取pieces,并将等待链接器计算出位置。我还建议了一个“初学者”。数组的函数。我没有发布'发布'然而,功能在于。

注意这是C,而不是C ++。如果你正在使用C ++,你应该真的使用new或更好,使用vector

此外,在C ++中使用静态时,请注意:C++ static initialization order

答案 2 :(得分:1)

For high performance code on various architectures, you may want a malloc-y allocation rather than generic new. That is because you would wrap it with something like mymalloc() and then use architecture dependent functions, such as ones that implement the proper alignment to avoid cache misses and do other nifty things provided by the hardware manufacturer, such as IBM (Bluegene) or Intel (MIC). All of these optimized allocation routines have the malloc type framework.

答案 3 :(得分:1)

在C ++ 17标准中,可以使用inline说明符而不是静态说明符。对于变量,这意味着每个对象单元都将具有该变量的副本,但是链接器将仅选择其中之一。 或者,如cppreference所述:

  

内联函数或内联变量(自C ++ 17起)具有以下内容   属性:

     

1)内联的定义可能不止一个   程序中的函数或变量(自C ++ 17起),只要每个   定义出现在不同的翻译单元中,并且(对于非静态   内联函数和变量(自C ++ 17起)所有定义均为   相同。例如,内联函数或内联变量   (自C ++ 17起)可以在#include中的头文件中定义   多个源文件。

     

2)内联函数的定义或   变量(自C ++ 17起)必须存在于翻译单元中,其中   它已被访问(不一定在访问点之前)。

     

3)具有外部链接的内联函数或变量(自C ++ 17起)   未声明为静态)具有以下附加属性:

1) It must be declared inline in every translation unit.

2) It has the same address in every translation unit.

({source)中受支持:

  • 自版本19.12(VS 2017 15.5)起的MSVC
  • 海湾合作委员会7
  • Clang 3.9
  • ICC 18.0

在这种情况下,这意味着您可以替换

static int *pieces;

inline int *pieces;