3

如果您有一个变量,则有一个与该变量关联的内存地址,对于指针变量,该内存地址的“值”是对保存指针指向的实际数据的内存地址的引用.

所以如果我有:

for (int x = 0; x < 2; x++)
{
    char * a = (char*)malloc(20);
    printf("%p\r\n", &a);
    printf("%p\r\n", a);
}

输出应该是这样的:

    00999999
    04427310
    00999999
    0442ECF0

正如您所看到的,在每次循环过程中声明的指针变量的第一个和第三个内存地址保持不变,我的理解是,这是因为前一个变量超出范围而下一个可用地址是同一个地址。

这种概括可以扩展到循环内声明的所有变量还是有例外?

4

2 回答 2

11

不,您不能概括这一点,并且不能保证a(指针,而不是它指向的内容)的内存在每次迭代中都是相同的。在这种情况下,内存被重用,它很可能总是相同的,但没有任何保证。

另请注意,您有内存泄漏。

于 2012-12-13T13:33:23.213 回答
3

这就是堆栈通常的工作方式。这与变量类型无关。当堆栈向下增长时,它可能看起来或多或少像这样

<top>
|                 |
+-----------------+
| argument1       |
| argument2       |
+-----------------+
| return address  |
+-----------------+
| saved register1 |
| saved register2 |
+-----------------+
| local variable1 | <- base register
| local variable2 |
| x               |
| a               |
|                 | <- stack pointer
<bottom>

编译器将堆栈上的空间分配给相对于某个基址寄存器的每个变量。当循环范围结束时,空间 fora有效地变为“空闲”并且可以重用。

如果稍后有第二个循环或其他一些嵌套范围

for (int x = 0; x < 2; x++)
{
    char * a = (char*)malloc(20);
    printf("%p\r\n", &a);
    printf("%p\r\n", a);
}
...
for (int x = 0; x < 2; x++)
{
    char * b = (char*)malloc(20);
    printf("%p\r\n", &b);
    printf("%p\r\n", b);
}

b可能会重用以前由 占用的空间a,因为 a 不再需要它。这一切都取决于编译器如何优化堆栈上的空间。

这就是它至少在编译后的 C 类语言中的工作方式。当然,还有其他内存模型。

于 2012-12-13T13:44:18.797 回答