在堆栈上声明内存将覆盖先前声明的内存

时间:2019-03-24 18:19:58

标签: c stack alloca

如何在堆栈上分配内存并将其指向不同的内存地址,以便以后使用?例如。此代码:

for (int i = 0; i < 5; i++) {
    int nums[5];
    nums[0] = 1;
    printf("%p\n", &nums[0]);
}

每次都会打印出相同的地址。如何将内存写入堆栈(不是堆,没有malloc),并且不覆盖已经在堆栈中的其他内容。

2 个答案:

答案 0 :(得分:1)

您可以使用alloca为循环中的每次迭代分配一个与运行时堆栈不同的数组。数组内容将保持有效,直到您退出函数为止:

#include <stdlib.h>
#include <stdio.h>

void function() {

    for (int i = 0; i < 5; i++) {
        int *nums = alloca(5 * sizeof(*nums));
        nums[0] = 1;
        printf("%p\n", (void *)nums);
        /* store the value of `num` so the array can be used elsewhere.
         * the arrays must only be used before `function` returns to its caller.
         */
        ...
    }
    /* no need to free the arrays */
}

但是请注意,alloca()不是C标准的一部分,可能并非在所有体系结构上都可用。有关如何使用它的其他限制,请参见系统的文档。

答案 1 :(得分:0)

我相信您正在寻找:

  

一种控制内存如何在堆栈上分配的方法,至少在不覆盖已用内存的情况下

当然,这已经由OS负责!低级系统调用将确保不会在已经使用的内存块上写入新创建的自动变量。

在您的示例中:

for (int i = 0; i < 5; i++) {
  int nums[5];
  ...
}

这不是 情况,因为当for循环的第i次迭代终止时,nums超出范围

因此,在第一次迭代期间将存储块nums存储到第二次迭代时将其标记为空闲,这意味着当第一次迭代的nums将要进行被分配到堆栈中时,它不会知道第一次迭代的nums是否存在,因为它已经超出范围了-它不存在!