2010-03-10 113 views
3
  1. 静态变量是否存储在堆栈本身中,类似于全局变量?如果是这样,他们如何保护只允许本地课程访问?内存中的静态变量和全局变量

  2. 在多线程环境中,是否担心这个内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

+3

我预测在未来的10分钟内这将获得3个upvotes,尽管之前已被问过一千次。哦,我应该说至少有3个回复,来自知道这是一个愚蠢的人。 – 2010-03-10 22:51:54

+1

也许如果你没有影响它。 – Ponkadoodle 2010-03-10 22:54:36

+0

尽管我希望通过upvoting使你的预测成真,但我想我会放弃这一点.... – 2010-03-10 22:55:46

回答

3

存储在堆栈中的变量在本质上是暂时的。它们属于函数等,当函数返回并弹出相应的堆栈框架时,堆栈变量随之消失。由于全局变量被设计为可以在任何地方访问,因此它们不能脱离上下文,因此它们被存储在堆(或二进制文件的特殊数据段中)而不是堆栈中。 static变量也是如此;因为它们必须在函数的调用之间保持它们的值,所以当函数返回时它们不会消失,因此它们不能在堆栈上分配。

就变量的保护static而言,IIRC主要由编译器完成。即使变量位于堆上,编译器也知道该变量有效的有限上下文,并且任何尝试从该上下文外部访问static都将导致“未知标识符”或类似错误。唯一不正确访问堆变量的方法是如果您知道static的地址,并且您盲目地取消引用它的指针。这应该导致运行时内存访问错误。

在多线程环境中,使用全局变量和静态变量仍然可以。但是,你必须更加小心。您必须保证一次只有一个线程可以访问变量(通常通过某种锁定机制,例如互斥锁)。对于函数内部的局部变量,您必须确保您的函数仍然按照预期的方式工作(如果它是从多个线程依次调用的)(即从线程1调用,然后从线程2调用,然后调用线程1,然后调用线程2等等)。这通常很难做到,并且许多依赖于static成员变量的函数由于此而不是线程安全的(strtok是一个值得注意的示例)。

+1

你能举出任何支持“静态变量不能分配在堆栈上并且它们存储在堆中”的链接吗? – bubble 2012-01-27 17:01:12

1

存储类似于全局栈本身的静态变量?如果是这样,他们如何保护只允许本地课程访问?

不,static仅指存储时间长度 - 它们可能是全局的或具有本地范围。全局有静态存储。

在多线程环境中,是否担心这个内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

多位作家会引入歧义。您需要使用互斥锁或某些此类锁定机制来保护共享资源。

2

静态变量存储在堆栈本身类似于全局变量吗?如果是这样,他们如何保护只允许本地课程访问?

一般而言,它们与全局变量一起存储在内存中。但是变量名称的可见性限制了访问。

在多线程环境中,是否担心这个内存可以被其他线程/内核直接访问?或者为什么我们不能在多进程/线程环境中使用静态/全局?

的问题是,有一个静态的只有一个副本,因此如果将多个线程修改变量,一个线程可能会导致失去另一个线程的变化如果没有保障(关键部分),以防止这种。

+0

如果它是一个线程特定的静态数据呢?它对其他线程是不可见的,访问它的唯一方法是通过直接内存寻址,是正确的? – Swapna 2010-03-10 23:07:23

+0

如果你的意思是它在线程本地存储中,那么没有问题(除非你将地址传递给其他东西)。如果它的作用域是一个线程过程(例如),那么可能仍然存在问题 - 多个线程实例可能执行相同的线程过程(或从其调用的其他函数)。 如果你的threadproc只会运行一个线程,那么你不必担心保护那个threadproc本地的静态。 – 2010-03-10 23:45:13

3

静态变量具有静态存储持续时间,所以它们通常不会放在堆栈上。对他们来说唯一的“保护”是他们的名字在编译时具有本地可见性。传递一个静态变量的地址可以访问它。

在多线程情况下使用静态/全局变量有一个问题,即如果一个线程在另一个尝试读取它的同时修改该变量(仅举一例),读取的内容可能是错误的数据。

+0

因此静态变量和全局变量都在堆内存中? – Swapna 2010-03-10 23:05:42

+4

不一定。该标准没有定义“堆栈”或“堆”,所以假设所有内存属于一个或另一个是不正确的。通常全局变量存储在与程序(和进程)相关的数据段中。从操作系统的角度来看,这可能是从堆中分配出来的,但是从操作系统的角度来看,堆栈很可能是从堆中分配出来的。 – 2010-03-10 23:23:01