C语言数组越界写入内存:考试答题是否应记录未分配内存赋值?
考试中未定义行为题目的答题建议
先拆解程序的执行逻辑和内存变化:
- 数组
k是5行7列的int数组,共占用35个int的内存空间,初始全为0。 - 初始化阶段:
p指向k[1](即数组第二行第一个元素),给*p赋值12,此时k[1][0] = 12。 - for循环执行过程:
- 第1次循环(i=0):
z = p + 8,从k[1][0]向后偏移8个int,对应k[2][1](每行7个元素,偏移7个到下一行开头,再加1就是该行第2个元素),赋值*z = 12 + 2 = 14,此时k[2][1] = 14,p更新为z。 - 第2次循环(i=1):
z = p + 8,从k[2][1]向后偏移8个int,对应k[3][2],赋值14 + 2 = 16,此时k[3][2] = 16,p更新为z。 - 第3次循环(i=2):
z = p + 8,从k[3][2]向后偏移8个int,此时已经超出数组k的内存范围(数组最后一个元素是k[4][6]),访问*z属于未定义行为——C语言标准对这种操作没有任何规定,实际运行可能触发段错误,也可能随机覆盖其他内存,但结果完全不可预测。 - 第4次循环(i=3):如果前一次操作没崩溃,
p已经指向非法内存区域,后续操作同样是无意义的未定义行为。
- 第1次循环(i=0):
针对你的问题,答题时的处理建议:
- 从语言标准的严谨性来说:不应该记录未分配内存的赋值。未定义行为的结果没有任何可靠性,不存在所谓“正确”的值,强行记录本质上是错误的。
- 从考试得分的现实角度:如果教授明确会认可这种超出范围的赋值记录,你可以按照教授的预期书写,但必须清楚这不符合C语言的规范。更稳妥的做法是:
- 写出数组
k范围内所有合法修改后的值:k[1][0] = 12、k[2][1] = 14、k[3][2] = 16,其余数组元素保持初始值0。 - 明确标注第三次循环及之后的操作属于未定义行为,无法确定内存中的值,实际运行会触发段错误。
- 写出数组
内容的提问来源于stack exchange,提问作者user18715126
相关产品推荐
相关产品推荐

