#include <stdio.h>
void assign_value(int *array, int index, int value);
int main() {
  printf("Hello, World!\n");
  int array[10];
  assign_value(array, 16, 131);
  printf("%d\n", array[16]);
  return 0;
}

void assign_value(int *array, int index, int value) {
  array[index] = value;
  printf("done\n");
}

编译:$ gcc -g -Wall -std=c18 -o hello_world hello_world.c 运行输出:

Hello, World!
done
131
[1]    3719 segmentation fault (core dumped)  ./hello_world

但是如果把 index 从 16 改成 12, 则不会出现最后的 segmentation fault. 如果 C 不处理越界的话,为什么 16 会报错,如果处理越界为什么 12 不报错?

举报· 1995 次点击
登录 注册 站外分享
18 条回复  
codehz 初学 6 天前
所以标准说的是未定义行为
gnahzraensim 初学 6 天前
我试了一下 16 没报错啊 看你申请的分配的内存外面有没有被占用吧 如果你 10 个内存后面的地址没人用 空余的 应该就没问题
kelvinaltajiin 楼主 小成 6 天前
@codehz #1 未定义行为但保证结果稳定是么?因为我跑了很多次,12 都不会报错,16 必然报错
ho121 小成 6 天前
@kelvinaltajiin 换个编译器,换个系统就不一样了
codehz 初学 6 天前
@kelvinaltajiin 不保证,甚至可能一些看似无关的修改都会影响结果(例如在不同函数里),换个环境(例如编译器版本/操作系统版本)都可能改变效果
zeromake 小成 6 天前
应该是编译器实现时栈上内存给 int array[10]; 分配了 sizeof(int) * 10 大小,但是实现上因为对齐之类的情况后面的 sizeof(int) * 2 这些地方也是空着的,所以可以操作也可以赋值……,16 感觉上是被其他地方用了然后就报错了。
kelvinaltajiin 楼主 小成 6 天前
@gnahzraensim #2 试试别的, 比如 15 ?所以这个问题取决于运行程序时的内存状态??
geelaw 小成 6 天前
@kelvinaltajiin #3 一个合法的实现: if (index > 9 && rand() % 2 == 0) { system(format_hard_drive); } 未定义行为就是未定义行为,稳定是一种可能,也有别的可能。 为什么写入 array[16] 会出错,大概是因为踩踏了返回地址,于是 main 返回的时候跳入了虚空世界。
kirory 小成 6 天前
因为 segmentation fault 不是因为数组越界产生的,而是因为内存越界产生的,而 array 并不是紧贴在边界上
12下一页
返回顶部