由char* 引发的Segmentation fault错误

由char* 引发的Segmentation fault错误

在学习形参带const限定符时,意外遇到Segmentation fault的bug问题。C程序是在linux环境下运行。

在维基百科上是这样解释Segmentation fault,存储器区段错误(Segmentation fault),又译为存储器段错误,也称访问权限冲是一种程序错误。它会出现在当程序企图访问CPU无法寻址的存储器区段时。当错误发生时,硬件会通知操作系统产生了存储器访问权限冲突的状况。操作系统通常会产生核心转储(core dump)以方便程序员进行调试。通常该错误是由于调用一个地址,而该地址为空(NULL)所造成的,例如链表中调用一个未分配地址的空链表单元的元素。数组访问越界也可能产生这个错误。

在本篇文章里通过几个案例来分析由char * 引起的Segmentation fault。

我们先来看一个关于使用char* 的案例

#include

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

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

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

#include

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;

}

文章到此结束,希望能带来一点点收获