【问题标题】:In C language, Static Variable with pointer access在 C 语言中,具有指针访问的静态变量
【发布时间】:2017-06-08 06:37:41
【问题描述】:

我的问题是关于内存以及如何在具有多个 C 文件(多个模块)的程序中访问它。

file1.h 版本 1

    #ifndef file1_h
    #define file1_h

    typedef struct
    {
      UINT8  var1;
      UINT16 var2;
      UINT16 var3;
    } TestAccess;

    static TestAccess* pLongRangeAccess;

    #endif

file1.h 第 2 版

    #ifndef file1_h
    #define file1_h

    typedef struct
    {
      UINT8  var1;
      UINT16 var2;
      UINT16 var3;
    } TestAccess_t;

    TestAccess_t* pLongRangeAccess;

    #endif

Main.c

#include "file1.h"

void main(void)
{
  pLongRangeAccess->var1 = 4;
  pLongRangeAccess->var2 = 8;
  pLongRangeAccess->var3 = 16;
}

模块1.c //需要对结构变量进行读/写访问

#include "file1.h"

void module1(void)
{
  pLongRangeAccess->var1 = 5;
  pLongRangeAccess->var2 = 10;
  pLongRangeAccess->var3 = 20;
}

问题 1)请参阅“Version1”关键字中的静态是否使得堆内存中只有一个副本(未初始化),因此只有一个指针变量的地址,或者它会创建 2 个具有不同内存的静态变量,因为每个模块都使用标头?

问题 2) 参见“版本 2” 如果没有为指针变量声明 static,那么它仍然在堆内存中,并且会有一个唯一的地址可用于访问成员的读写操作?

问题 3) 在 file1.h 的版本 2 中,如果指针在 Main.c 中声明,并且内存位置是固定的,即声明为常量,是否可以通过取消引用从任何模块访问它内存地址位置?

【问题讨论】:

  • 我看到 3 个问题,这很宽泛。
  • 你不在头文件中声明静态变量。而且这些代码中的任何地方都没有堆内存。
  • 总的来说,永远不要在头文件中声明任何变量。非常糟糕的程序设计,往往会导致各种链接问题。
  • 这些都不在“堆”上。 static 表示静态存储持续时间和链接,将其视为编译单元私有的全局变量。您可能正在寻找的是extern
  • “因此只有一个指针变量的地址,或者它会创建 2 个具有不同内存的静态变量”,这看起来像 XY problem

标签: c pointers memory


【解决方案1】:

我认为您将“内存分配”与变量声明和变量定义混为一谈。我认为你想要的是在不同的翻译单元之间共享一个变量pLongRangeAccess,这样它在你的程序中只存在一次。为此,声明头文件中的变量,并在单个 c 文件中定义一次:

#ifndef file1_h
#define file1_h

typedef struct
{
  UINT8  var1;
  UINT16 var2;
  UINT16 var3;
} TestAccess;

extern TestAccess* pLongRangeAccess;

#endif

然后是.c-文件:

// file1.c:
#include "file1.h"
TestAccess* pLongRangeAccess;

注意关键字static,当应用于任何函数之外的变量时,意味着这个变量是各自翻译单元私有的;这主要是为了隐藏信息并避免与其他翻译单元(可能来自不同供应商)发生意外的名称冲突。

所以,如果你写

// file1.c
static TestAccess* pLongRangeAccess;

// file2.c
static TestAccess* pLongRangeAccess;

,那么翻译单元file1file2都有自己的私有变量pLingRangeAccess,对其他翻译单元是不可见的(无论是否有任何头文件将变量声明为extern)。在这种情况下,链接器不会抱怨任何“重复的变量定义”,因为 - 如前所述 - 变量对其 TU 是私有的。

但是,如果您编写以下内容

// file1.c
TestAccess* pLongRangeAccess;

// file2.c
TestAccess* pLongRangeAccess;

,那么这两个变量都对其他翻译单元可见,链接器会抱怨变量pLongRangeAccess在你的程序中定义了两次,这是不允许的。

【讨论】:

  • 现在已经很清楚了。我看到您在 file1.c 文件中将其定义为静态。静态意味着这个指针变量只能被 file1.c 中的任何函数访问。需要访问 pLongRangeAccess 的任何其他文件是否需要类似的语法?
猜你喜欢
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-30
  • 2010-10-19
  • 1970-01-01
相关资源
最近更新 更多