C ++指针和内存分配

时间:2016-06-17 16:37:34

标签: c++ pointers memory-management

我在教自己C ++。这是我的第一个编程语言,我正在努力解决与指针内存分配相关的措辞。

考虑这个陈述:

int *p;
int x;
p = &x;
*p = 8;

          Value
&p        1400
p         1800
*p        8
x         8

& p是p。

的内存地址

p是指针p指向的内存地址。

* p是指针p指向的内存地址的值。

我理解这一点。然而,该书指出:

p =& x将p的地址存储在p中。但是,没有分配新的内存。

这令人困惑。已经分配了内存,否则p将是未定义的。

现在考虑这个陈述:

int *p;
p = new int;
*p = 28;

在这里,你不需要一个额外的变量来使* p有效且有意义,因为已经分配了内存。

所以,我想我的问题是:

当考虑代码块时,作者对他的陈述“内存未分配。”的含义是什么?

7 个答案:

答案 0 :(得分:1)

通常,单词“已分配”用作“已分配 堆存储 的缩写”,使用“new”关键字,一个库例程,例如'malloc ',或其他一些此类机制(直接或间接)'。

这里的陈述'p =& x;'表示p的值设置为x的存储地址,在堆栈 中分配 。由于堆栈存储是自动管理的,而不是由程序员自行决定,因此我们选择在通俗用法中不将其称为“已分配”。

答案 1 :(得分:1)

  

p =& x将p的地址存储在p中。但是,没有分配新的内存。

100%是真的。所有的分配都在前两行完成。

int *p; // allocation of p here
int x; //allocation of x here 
p = &x; // no allocation here. 

p = &x;只是将先前分配的内存的位置分配给先前分配的指针。是否在堆栈上分配存储,堆或当前系统使用的任何内容而不是堆栈或堆都是无关紧要的。

对于第二个例子,

int *p; //allocation of p here
p = new int; // allocation of one nameless int AND assignment of that int to p here
*p = 28; // no allocation

答案 2 :(得分:0)

首次声明变量时,在堆栈上分配内存。这里,内存分配 int *p; int x;

因此,p = &x;将x的内存地址存储在先前为堆栈中的p分配的内存中。

答案 3 :(得分:0)

“p =& x将p的地址存储在p中。但是,没有分配新的内存。”

我认为这可能只意味着在这个特定的语句中,p取x的地址,并且没有为x分配新的内存。 x的内存可能是早先分配的,但是p的初始化没有为x分配新的内存。

但在后一种说法中

int *p;
p = new int;
*p = 28;

指向已分配的新内存块,因为它是使用“new int”初始化的。

答案 4 :(得分:-1)

" p =& x将p的地址存储在p中。但是,没有分配新内存。"因为' x'是在堆栈上创建的,而不是在堆上创建的(就像变量' p'以及所有其他'局部变量')。看来你的第二个例子是不正确的,但我并非100%肯定。

答案 5 :(得分:-1)

作者可能是指堆分配。 p和x都分配在堆栈上,这实际上只是递增(或递减,取决于机器类型)堆栈指针。当他们超出范围时,他们会被解除分配。 OTOH,new int从堆内存中分配它,这可能需要更多的时间来完成,但可以比它的范围更长寿:你使用delete手动释放它。无论哪种情况,指针都运行良好:这可能一开始并不明显,但您可以获取堆栈上的变量地址或使用相同类型从堆中分配的变量的地址。

答案 6 :(得分:-1)

我收到那本书,其他人提供的解释是正确的。只是添加我的。

编译函数时,除非它是变量参数1,否则编译器已知帧大小和格式。现在,当您调用此函数时,编译器会在调用方函数上方(或下方)的堆栈上保留此帧的内存。你可以自己看到这种情况。

void fun(){
int a,b;
printf("addr fun &a=%u, &b=%u",&a,&b);
callfun();
}

void callfun(){ int c;
printf("addr callfun &c=%u",&c);
}

在大多数架构上,地址可能看起来有所下降 - 但通过调用 calllfun()来逻辑地,我们在前一帧上创建了 帧。

因此,可以说这些变量的内存是透明创建的,程序员从不关心它。当堆栈增长时,使用更多内存,并在函数调用更接近主入口点函数时释放。但在其他情况下,当您使用new运算符时,程序员除了已经在堆栈上分配的内容之外还显式请求内存。这是通过程序的地址空间中名为的另一个区域来实现的。操作系统为此提供了便利。

在你的情况下,作者只是说由于已经调用了携带所有这些变量的函数,因此在进程中已经分配了(在堆栈上)内存并且没有创建新内存。但是,如果需要,可以使用 new 运算符分配更多内存。