为什么指针指向内存而不是值?

时间:2011-11-05 03:23:15

标签: c++ pointers

我目前正在学习C ++ Algorithms类中的指针,虽然我理解了这些材料,但我不明白为什么C ++指针指向一个内存插槽而不仅仅是一个你以后可以改变的特定值。 / p>

看起来您希望能够在指针占用的内存插槽中动态创建一个新变量。

是因为操作系统在堆上创建了所有动态变量,我们需要一种方法来查找它们,因为我们的指针是在程序加载时生成的吗?

如果就是这样,那么我完全明白了,但如果那不是它那么它似乎完全浪费了内存空间和一个额外的过程,我们的程序必须通过它来访问指针的目标值。

5 个答案:

答案 0 :(得分:2)

实际上,在你有大对象的情况下保存内存(大的意思是大于4或8个字节,即sizeof(void *))。您只需传递一个指针 - 它比对象小 - 并以这种方式分配,而不是支付昂贵的复制和覆盖操作。

动态分配用于您无法提前预测的分配,例如可变大小的数组和根据条件可能需要或可能不需要的不同状态对象。你根本不浪费记忆。如果按值传递它们,则会浪费更多时间和更多内存。

指针本身是一个内存地址,但它指向的是内存中的值。这也适用于像int **这样的东西,因为它指向内存中的指针值。

操作系统不会动态创建它们。你告诉程序分配一个新对象或一个特定大小的内存块,操作系统只是给你。

您始终可以重复使用指针。例如,如果我为一个100字节的数组分配空间,我可以随时重用它,只要我保留一个指向它的指针,只要我不释放它,直到我完成那个空间(你实际上是鼓励这样做。)

答案 1 :(得分:1)

您的问题最好通过代码示例和A / B对比来说明。 (如上所述,这是相当抽象的,很难知道你的意思。)

C ++为您提供了在“堆栈”或“动态”分配内容的选择:

/* foo is an integer on "the stack" */
int foo = 1;

/* bar is a pointer on "the stack", *bar is an integer on "the heap" */
int* bar = new int (1); 

bar&foo都指向值为1的整数。确实,bar不仅为该整数消耗内存,而且还为跟踪指向它的指针的堆栈变量消耗内存。

问题是,一旦函数或块作用域结束,堆栈上声明的变量就会消失。然而,有时您希望之后谈论对象或数量,并明确地管理其生命周期。在这些情况下,作为指针的这种“不必要的”描述性术语变得必要。

在所有条件相同的情况下,您不应使用动态分配。 C ++程序员经常试图鼓励C程序员重新考虑他们的代码而不需要它。但是,就为什么要避免这种做法而言,这个“存储指针”的额外内存是您最不关心的问题。这主要是关于最终做delete ...

的工作的悬空责任

答案 2 :(得分:1)

为了增加其他一些好的答案,我认为理解计算机的工作方式也有助于理解指针以及我们为什么需要它们。用我自己的话说 - 计算机中的每个逻辑操作都由CPU完成(当然,在最简单的情况下)。 CPU本身的内存极少。例如,32位i386 CPU有8 registers它可以操作,其中每个寄存器只能容纳4个字节的数据(32位)。所以32个字节都适合CPU。其余数据存储在其他circuits中,如CPU cacheRAM等。因此,当您希望CPU执行某些操作时,您必须要求它从外部电路加载数据,并且那就是你需要“指向”CPU到你想要它加载的内容,你必须给它一个内存的“地址”。 C指针就是那些地址,为您提供这种高级语言中最低级别的寻址存储位置。

现在,程序中的所有内容都放在内存中(甚至CPU寄存器在技术上都是内存,但它们的处理方式不同)。是堆栈上的某个值,还是动态分配的内存区域(毕竟,堆栈也是动态分配的),并且您始终可以通过它们在内存中的地址来引用这些对象。指针本身是一个值(i386上的4个字节或amd64上的8个字节),它保存地址(是的,您也可以指向该值,创建指向指针的指针)。因此指针无处不在,即使你没有看到它们。例如,当你复制一些大的“对象”时,必须分配存储器以保存该对象的副本,然后必须指示CPU将字节从源存储器区域复制到目标存储器区域,逐字节,解决这些字节“通过指针”(即here是实际CPU指令在汇编程序中的样子。)

即使在像Java这样的极高级语言中,指针也随处可见。它们只是对开发人员隐藏。

希望它有所帮助!

答案 3 :(得分:0)

  

为什么C ++指针指向一个内存插槽而不是一个   您可以稍后更改的某些值。

如果是这样,你为什么需要指针?还要注意指针是一个二合一的提议,同时指向一个内存位置,你也可以访问指向内存的值,比如说,

int a;
int *b;
b=&a;

 b >> memmory location
*b >> value

这是一个很好的教程:Pointers and Memory

答案 4 :(得分:0)

我不确定我是否完全理解这个问题,但我怀疑你是否对指针不正确做了一些隐含的假设。

你质疑为什么C ++“使指针指向一个内存插槽,而不仅仅指一个你可以在以后更改的值”。但是内存中的插槽实际上是存储值的唯一有效位置!这是一个合理的近似值,可以说整个程序中的所有数据都存储在一大组插槽中。这就像一个巨大的阵列。

记忆和价值观紧密交织在一起。你不能没有另一个,没有其他方法来存储东西(除了,可能存储到磁盘 - 是的,也有寄存器,但C / C ++抽象了那些)。

我还想解释你怎么说“看起来你希望能够在指针占用的内存插槽中动态创建一个新变量。”

指针占用的位置填充了指针值的位置(“指向”的位置)。如果你要在该槽中创建一个新变量,你将失去对指针指向的所有知识!因此,我们必须使用我们需要的值来保留内存插槽。

“是不是因为操作系统在堆上创建了所有动态变量,我们需要一种方法来查找它们,因为我们的指针是在程序加载时生成的?”

我不太确定“动态变量”是什么意思,但不是,并非所有指针都存储在堆上。简单的例子:

int a = 5;
int *b = &a;

请注意,b是指向a的指针,但ab都在堆栈上,而不是堆。

如果动态是指“使用new创建”,那么是的,可以公平地说,使用new创建的所有内容都是在堆上创建的。

另一个重要注意事项:操作系统(通常)不管理内存分配。它会做的最多就是给你一大堆堆内存来做你想做的事情。如果您有兴趣,请查看名为malloc的C例程,这是一种在堆上分配内存的方法,与new非常相似。它背后真的没有太大的魔力。

相关问题