即SIGSEGV。
参考文献:

原因

错误的访问类型

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main() {
  4. char* s = "hello world";
  5. s[1] = 'H';
  6. ...
  7. }

指针变量s指向了常量字符(位于常量区),该区内存是只读的,不可对其进行更改。

访问了不属于进程地址空间的内存/访问受系统保护的内存地址

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main() {
  4. int *str = (int *)0x20000000;
  5. *str = 555;
  6. system("pause");
  7. return 0;
  8. }

访问了不存在或已被free掉的内存

如解引用空指针。

#include <stdio.h>
#include <stdlib.h>
int main() {
    int a = 555;
    int *str = &a;
    *str = 666;
    str = NULL;
    printf("str ==%d", *str);
    system("pause");
    return 0;
}

发生了SIGSEGV。

解引用野指针。

#include <stdio.h>
#include <stdlib.h>
char *getStr() {
    char str[] = "hello world";
    return str;
}
int main() {
    char *str;
    str = getStr();
    printf("str == %s",str);
    system("pause");
    return 0;
}

这种情况并不一定会发生SIGSEGV。
getStr函数返回指向常量区的指针是没有问题的,不过值得注意的是,该段内存,在函数结束后便被free()了(同时被清零),因此输出结果是空值(力扣的运行结果如下)
str == (null)

栈溢出(不一定会引起SIGSEGV)

详情见原文。

堆溢出(同上)

下标越界

#include <stdio.h>
#include <stdlib.h>
int main() {
    int arr[10] = { 0 };
    int i = 0;
    for (i = 0; i < 100; i++) {
        arr[i] = 6;
    }
    printf("%p",arr);
    system("pause");
    return 0;
}

非法的系统调用参数

拓展

assert()函数

assert宏的原型定义在中,其作用是如果它的条件返回错误,则终止程序执行。

原型

void assert(expression)判断expression的值,若为假则停止运行。

注意事项

  1. 只写一个判断条件,否则终止时无法判断是哪个条件出了问题。
  2. 不能使用改变环境的语句如assert(i++<100)因为如果判断为假,那么i++不会执行。