一般如果c和c++中使用了指针编程,如果不注意使用,很容易出现segmentation错误,如果代码中的错误日志不够的话,还在真不太方便定位,尤其是使用了大量指针的情况下。
网上总结的有下面几条,我这里摘抄一下
- 访问了空指针:如
char* p;printf("%s\n", p);
p指针没有初始化分配内存空间,p的值一般为0 NULL - 指针越界,实际也是访问了空指针:int p[100];p[100]=1;
- 常量被修改
char *p = "abcd"; p[1]=e;
- 在一些比较老的操作系统上,非对齐访问也可能导致segmentation fault
int
a[2];
char
*p1 = (
char
*)a;
//指向数组首地址。
int
*p2 = (
int
*)(p1+1);
//实际上将a[0]和a[1]的各一部分,组成了一个新的int。 这时对p2的访问,包括读写,都属于非对齐访问。
*p2=3;
//此时有可能出现segmentation fault
还有一种情况,是在使用比较复杂的指针时会出现,如果结构体中含有指针,而本身结构体定义了一个指针变量,如果没有执行清0步骤,结构体中的成员初始值将是不可预见的。
比如我的例子,在代码中我定义了如下结构体,使用链表和递归来获取xml文件所有节点的内容,引用了tinyxml.so库
在用
tXmlNodeEntireDef * pNode = (tXmlNodeEntireDef *)malloc(sizeof(tXmlNodeEntireDef))
//没有按照开发规范,使用meset进行初始化
memset(pNode, 0 ,sizeof(tXmlNodeEntireDef)
刚开始在xml简单时没有问题,但xml稍微复杂就上报错误:segmentation fault,中间打印了很多东西,最后把结构体变量中的
attriListNode的地址打印出来后才定位到,本来刚开始调用的应该是NULL,但却莫名奇妙的有值,于是判断到不等于NULL,就直接拿来用,实际这个值是不可用的,用了后导致上报segmentation fault ,访问了非法地址
作为初学走了不少弯路,以前实际也用过,每次都会按照规范memset一下,但这次就忘了,而且有时还认为无关紧要
所以开发时一定要严格按照规范走!