【问题标题】:What are the differences and similarities between global variables and heap variables in c?c语言中的全局变量和堆变量有什么区别和相似之处?
【发布时间】:2012-12-12 01:47:23
【问题描述】:

c中的全局变量和堆变量有什么区别和相似之处?

假设我有这段代码。

const char* globalVar = "This is a string";

int main(int argc, char* argv[]){
    char* heapVar = malloc(7 * sizeof(char));
}

那么 globalVar 和 heapVar 有什么区别和相似之处呢?

提前致谢。

【问题讨论】:

  • 为了安全起见,将其设为 const char*,因为您不能在该字符串上写字。
  • 注意:您的heapVar 实际上是一个自动(“堆栈”)变量,它指向堆存储。一旦 main() 返回或退出,'heapVar` 将不再存在,但 它所引用的对象 仍然存在。对于 main() 这当然是一个小问题,(如果 main 返回,则程序不应该再存在,除了 atexit 处理程序),但对于“普通”函数,区别非常明显。结果是内存泄漏。
  • +1 请注意,wildpasser 说:heapVar 指向堆存储,但它在堆栈中。
  • 我们正在回答一个非常基本的家庭作业问题,OP 的教授希望 OP 能够通过关注他/她的笔记/教科书/课程材料来弄清楚。

标签: c global-variables heap-memory


【解决方案1】:

全局变量和堆变量是两个不同的概念。堆变量只是告诉你变量的空间分配在哪里,而全局变量告诉你变量的范围。

全局意味着变量对任何东西都是可见的,它与局部相反,意味着变量的可见性受到限制。

堆意味着变量(指针)是动态分配的(例如:使用malloc),与未动态分配变量的堆栈相反。

所以你可以有一个全局堆变量、一个全局堆栈变量、一个局部堆变量或一个局部堆栈变量。

在您的情况下, globalVar 是全局的,因为它是在任何函数的范围(大括号)之外声明的,而 heapVar 是 main 的局部变量。由于调用了 malloc,heapVar 在堆上声明。 globalVar 是一种特殊情况,因为它使用 char* 声明。

有关如何处理 char* 样式声明的更多详细信息,请参阅: Heap or Stack? When a constant string is referred in function call in C++

【讨论】:

    【解决方案2】:

    全局变量始终存在,它永远不会消失。此外,它在该文件/模块中的所有函数中都是可见的,除非声明为“静态”,否则它在整个文件/模块中也是可见的。

    请注意,您的全局变量不是“这是一个字符串”,而只是那个 globalVariable,它只是一个指针(包含内存中的地址)。

    heapVar 变量包含指向堆上某物的地址。该变量仅在 main() 函数中可见。

    可以使全局变量指向堆。

    这里的区别是globalVariable指向的内容是静态分配的,而heapVar指向的内容是动态分配的(可以通过调用free()来销毁它并释放内存,而不能释放那个字符串使用的内存)这是一个字符串”,即globalVar指向的内容)。

    【讨论】:

      【解决方案3】:

      注意:这里我讨论的是 globarVar 和 heapVar,而不是它们指向的内存。
      区别在于:

      范围

      heapVar 在堆栈中,而不是在堆中,因此它的作用域是其函数的本地范围,并且 globarVar 可以在任何地方评估。

      生活

      heapVar 在函数调用结束时死亡, globarVar 在程序的所有持续时间内都存在。

      关于他们指向的内存:

      heapVar 指向的内存在堆中,而 globarVar 指向的内存在实现定义的只读内存中,为了安全,将其设为 const char*:

      char* globalVar = "This is a string";
      

      堆中的内存可以随时释放,字符串在程序的所有持续时间内都存在。 在您的情况下,您有泄漏。无论如何,我知道这只是一个示例,也许您已经意识到了。

      【讨论】:

        猜你喜欢
        • 2018-04-23
        • 1970-01-01
        • 2016-01-17
        • 1970-01-01
        • 2022-06-16
        • 1970-01-01
        • 2011-01-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多