在最近的测试问题中,我被要求打印以下程序的输出。我得到的答案是正确的,但是这个程序给我带来了很大的精神痛苦,因为我不知道写入超出数组范围的内存时的行为是什么。
这是有问题的程序,评论是我的笔记:
#include <stdio.h>
#define MAX 4
void RecordArgs(int x);
int main()
{
RecordArgs(1);
RecordArgs(7);
RecordArgs(-11);
return 0;
}
void RecordArgs(int x)
{
static int i = 0;
int call_count = 0;
int arg_history[MAX] = {0};
if (call_count == MAX)
{
# call_count is not static and is initialized to 0 on each call
# as a result, under no circumstance can call_count == MAX and
# this printf is never executed
printf("Too many calls to RecordArgs\n");
}
else
{
# index out of bounds on second/third call (i + call_count will be 4??)
arg_history[i + call_count] = x;
++call_count;
++i;
for (i = 0; i < MAX; ++i)
printf("%d ", arg_history[i]);
printf("\n");
}
}
预期的产出:
1 0 0 0
0 0 0 0
0 0 0 0
当RecordArgs被调用时,第二次和第三次写入7和-11值的位置是什么?我尝试在不同的设置下编译它,看看我是否可以把它写入不应该写的东西,但我尝试过的所有内容都会导致确切的输出没有任何段错误。
答案 0 :(得分:2)
扩展Patashu的评论时,当您以与内存权限页面冲突的方式从页面访问内存时,会出现segmentation faults。换句话说,当您以不允许的方式访问内存页时,就会出现这种情况。在您的情况下可能发生的是您仍在访问存储arg_history
的同一页面内的内存,您显然有权读取和写入。
另一种可能的情况是,您正在处理的内存页面具有相同的权限,允许您以相同的方式访问它。
在任何情况下,这都是C中的未定义行为。虽然您见证了“预期结果”,但不应向您表明该程序是正确的。实际上,如果不会导致分段错误,这种情况下可能会忽略越界错误。