在学习形参带const限定符时,意外遇到Segmentation fault的bug问题。C程序是在linux环境下运行。
在维基百科上是这样解释Segmentation fault,存储器区段错误(Segmentation fault),又译为存储器段错误,也称访问权限冲是一种程序错误。它会出现在当程序企图访问CPU无法寻址的存储器区段时。当错误发生时,硬件会通知操作系统产生了存储器访问权限冲突的状况。操作系统通常会产生核心转储(core dump)以方便程序员进行调试。通常该错误是由于调用一个地址,而该地址为空(NULL)所造成的,例如链表中调用一个未分配地址的空链表单元的元素。数组访问越界也可能产生这个错误。
在本篇文章里通过几个案例来分析由char * 引起的Segmentation fault。
我们先来看一个关于使用char* 的案例
#include <stdio.h>
void print (char *p1);
int main () {
print("2020-xx-xx");
return 0;
}
void print (char *p1) {
while ( *p1 != '\0' ){
printf("%c",*p1++);
}
printf("\n");
}
其运行结果为2020-xx-xx,看起来并没有什么问题。但在上面的基础上做一些修改,就会引发Segmentation fault错误,请看下面的案例
#include <stdio.h>
void print (char *p1);
int main () {
print("2020-xx-xx");
return 0;
}
void print (char *p1) {
char *p =p1;
while ( *p1++ != '\0' ){
if(*p1== 'x') {
*p1 = '1';//这一条语句会引发Segmentation fault错误
}
}
printf("%s\n",p);
}
从上面两个案例来说,实参是字符串常量时,通过形参指针进行访问并不会引发错误,而当你试图想要修改这个指针所指向的值,会引发Segmentation fault错误。
至于为什么会出现Segmentation fault错误,看下面的案例就能清楚了
#include <stdio.h>
int main () {
int *p1 =2;
int num=1;
int *p2= #
printf("*p1=%d\n",*p1);
printf("*p2=%d\n",*p2);
return 0;
}
当你编译这段程序时,会有警告信息:warning: initialization of ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
当你运行这段程序时,会有报错信息:Segmentation fault
当你试图向一个未初始化的指针赋值常量时,这往往会引发错误,因为你并不知道指针会指向哪里,这充满了未知!!总之,在使用指针要尽量小心,避免不必要的错误!!!!!
在第一个案例中,可以正常打印字符串,这为什么不会报错,有待进一步研究。下面是strcpy库的正确使用方法.
#include <stdio.h>
#include <string.h>
int main () {
char s1[] = "s1";
char s2[] = "s2";
char *pointer_1 = s1;
char *pointer_2 = s2;
//正确用法
printf("%s\n",strcpy(s1,s2) );
printf("%s\n",strcpy(pointer_1,pointer_2) );
//这条可以运行,但不推荐使用
printf("%s",strcpy(pointer_1,"s2") );
//下面会引发Segmentation fault
//printf("%s",strcpy("s1","s2") );
//printf("%s",strcpy("s1",pointer_2) );
return 0;
}
文章到此结束,希望能带来一点点收获
转载:https://blog.csdn.net/weixin_44546834/article/details/113824592
查看评论