让我们在下面考虑这段代码。
#include <stdio.h>
#define N 100
int main()
{
int n;
scanf("%d",&n);
if(n>0){
int m[N ][N] = {0};
}
return 0;
}
我想了解这段代码与内存有关的行为。我想回答以下问题:
答案 0 :(得分:3)
正如@dbush所说,代码只能在m
范围内合法访问名为if
的内存。
实际完成分配的位置将取决于编译器和优化器设置。
在没有优化的情况下,gcc和clang均会调整main入口处的堆栈指针(分配内存),但仅当n
非零时才将初始化执行为零。
通过-O3优化,它们都只调用scanf
并返回0,因为这是唯一可观察到的效果。编译器实际上都不会预留内存,也不会查看扫描的值,也不会尝试初始化。
答案 1 :(得分:1)
m
使用的内存仅在if
块的范围内有效。因此,如果要将指针保存在块外,则尝试在该块外取消引用该指针时将调用未定义的行为。
也就是说,实现可以选择为所有局部变量留出堆栈空间,而不管输入函数时的作用域如何。例如,如果我采用您的代码并将N
更改为2000,则应用程序在启动后立即立即进行核心转储,这表明该应用程序尝试为太大的对象在堆栈上分配空间。