segmentation fault(linux c)补遗

来源:互联网 发布:双截棍 知乎 编辑:程序博客网 时间:2024/05/16 12:50

一般如果c和c++中使用了指针编程,如果不注意使用,很容易出现segmentation错误,如果代码中的错误日志不够的话,还在真不太方便定位,尤其是使用了大量指针的情况下。

网上总结的有下面几条,我这里摘抄一下

  1.  访问了空指针:如
    char* p;printf("%s\n", p);
    p指针没有初始化分配内存空间,p的值一般为0 NULL
  2. 指针越界,实际也是访问了空指针:int p[100];p[100]=1;
  3. 常量被修改
    char *p = "abcd";p[1]=e;

  4. 在一些比较老的操作系统上,非对齐访问也可能导致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一下,但这次就忘了,而且有时还认为无关紧要


所以开发时一定要严格按照规范走!

原创粉丝点击