即SIGSEGV。
参考文献:
原因
错误的访问类型
#include <stdio.h>
#include <stdlib.h>
int main() {
char* s = "hello world";
s[1] = 'H';
...
}
指针变量s指向了常量字符(位于常量区),该区内存是只读的,不可对其进行更改。
访问了不属于进程地址空间的内存/访问受系统保护的内存地址
#include <stdio.h>
#include <stdlib.h>
int main() {
int *str = (int *)0x20000000;
*str = 555;
system("pause");
return 0;
}
访问了不存在或已被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的值,若为假则停止运行。
注意事项
- 只写一个判断条件,否则终止时无法判断是哪个条件出了问题。
- 不能使用改变环境的语句如
assert(i++<100)
因为如果判断为假,那么i++不会执行。