根据Warford的“计算机系统”(第4版),“当您声明全局变量或局部变量时,指定其类型。例如,您可以将类型指定为整数,字符或数组类似地,当你声明一个指针时,你必须声明它指向某种类型。指针本身可以是全局的或本地的。然而,它所指向的值位于堆中,既不是全局的也不是本地的。“< / p>
我知道您可以在堆栈中创建局部变量,在固定位置创建全局变量,并在堆中动态分配变量。指针只能指向动态分配的变量吗?为什么指针不能指向全局或局部变量?
由于
答案 0 :(得分:5)
然而,它指向的值位于堆中,既不是全局也不是本地。
这是不正确的。
指针只能指向动态分配的变量吗?
没有
为什么指针指向全局或局部变量?
他们肯定可以。
您可能希望更仔细地阅读本书,以了解书中的陈述是否是在某些其他背景下进行的。如果没有,是时候放弃这本书并从另一本书中学习。
答案 1 :(得分:1)
指针指向变量所在的内存中的位置。我不认为你应该关心它在哪里。即使在程序之外,您也可以指向绝对任何变量(但这很危险,也可能会使您的应用程序崩溃)。指针只是一个数字,内存中的地址。在许多情况下,您指向全局/局部变量。例如,如果要将类/数组传递给某个函数。
答案 2 :(得分:0)
指针可以指向局部变量或全局变量(或其中的字段)。但在这种情况下你可能更喜欢references。
指针也可以指向通过某种ad-hoc机制获得的内存。例如,Linux上的::operator new
会间接调用mmap(2)(或类似的系统调用),这会增加进程的virtual address space。或者在某些嵌入式处理器中,您有特殊的原语来获取一些内存(例如,切换memory banks)等等......
指针也可以指向虚拟地址空间之外的某个地址。然后解除引用它是undefined behavior,并经常提供segmentation fault。
但是,指向本地或全球数据通常(但并非总是)被认为是不好的品味。使用约定进行编码通常更简单,指针应该是堆分配的内存。另请阅读smart pointers(特别是std::shared_ptr)和reference counting。
(是使用指向call stack上的本地数据或全局数据的指针的一些很好的理由,但是应该用谨慎和谨慎;我可以通过研究现有的C ++源代码 - 例如free software)来了解更多关于它们的信息
另请阅读memory leaks和dangling pointers。你应该避免这两个。在Linux和POSIX系统上,了解valgrind(帮助寻找与内存相关的错误的工具)。
garbage collection的术语和概念对于了解非常有用。
一种常见的样式(对于存储在类或结构的字段中的指针),可以在构造函数中使用new
为它们分配内存,并在析构函数中使用delete
进行释放。
答案 3 :(得分:0)
指针可以指向任何对象,因此声明“它指向的值,但是,它位于堆中”至少是不完整的,实际上是错误的。指针可以指向任何对象,无论它是驻留在“堆栈”上,“堆”上还是位于相同的“固定”内存上,无论它是“全局变量”还是“局部变量”。请注意,所有这些术语都是不精确的,甚至在对象或指针的上下文中也没有在标准中使用。该标准只讨论storage duration个对象(自动,静态,动态),以及关于变量名称的scope(即可见性)(块,函数,命名空间,全局命名空间......)
所以唯一重要的是指针指向任何对象,无论其存储持续时间如何,但它不能被“使用”(即取消引用)在它指向的对象的生命周期开始之前或者在生命周期结束之后。否则,程序的行为是不确定的。
BTW:无论你的书多大了,都没有任何C ++标准,其中“始终指向堆”的陈述是真实的。