飞道的博客

由char* 引发的Segmentation fault错误

282人阅读  评论(0)

在学习形参带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= &num;

	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
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场