• basic coder » 写C程序时犯的超低级致命错误


    basic coder » 写C程序时犯的超低级致命错误

    写C程序时犯的超低级致命错误

    2010年3月7日
    levin 发表评论
    阅读评论
    4,541 人阅读过  

    这几天一直在用C写程序,对于C/C++的内存管理方面的机制总是很小心,每次malloc之后都记得一定要free,可却犯了一个最初始的低级错误。

    写了一个这样的函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    unsigned char* strtohex(const char* in , int* len)
    {
    	unsigned char* out = (unsigned char*)malloc(strlen(in)/2 );
    	int i = 0 , j = 0 , k = 0 ,length = 0;
     	char tmp[2] = { 0 };
    	memset(out , 0 , strlen(in) / 2);
    	while(i < (int)strlen(in))
    	{
    		tmp[k++] = in[i++];
                    tmp[k] = '\0';
    		if(k == 2)
    		{
    			out[j++] = (unsigned char)strtol(tmp , (char**)NULL , 16);
    			k = 0;
    			length ++;
    		}
    	}
    	if(len != NULL )
    		*len = length;
    	return out;
    }

    函数很简单,功能就是把一个16进制的字符串转换成unsigned char 数组,每两个字节转换成一个字节的unsigned char

    strtol函数的功能是将一个字符串转换成一个长整型,存在第二个参数里面,然后返回转换结果,第三个参数是进制数,这里是16进制。

    看上去没什么问题,但这个函数却给我带来了灾难性的后果,经常在free的时候会Segmentation fault ,仔细地检查各种malloc,各种长度都没有问题,可Segmentation fault 却时而出现时而不出现,当时就意识到自己犯了致命的错误,可却找不出在哪里,gdb也查不出问题所在。

    后来有一次调用这个函数做转换的时候猛然间发现对同一个字符串有时候的转换结果会不一样,仔细地检查了一下这个函数终于发现了错误的根源:

    	char tmp[2] = { 0 };

    这里定义了一个2字节的字符数组,在存储的是一个2字节的16进制字符串,居然忘了里后的一个\0,需要3个字节才够,真是晕了,即使在malloc的时候也会记得多malloc一个字节存储\0,在这里却大意了,狠狠地警示一下自己。

    原创文章,转载请注明: 转载自basic coder

    本文链接地址: http://basiccoder.com/faial-error-when-writing-c.html

  • 相关阅读:
    SpringBoot EnumValidator验证器实现
    【原创】SpringCloud:基于Spring Cloud netflix全家桶搭建一个完整的微服务架构系统
    Hystrix Dashboard监控报“Unable to connect to Command Metric Stream”?
    Mysql sql_mode的合理设置
    nginx 调优
    函数指针
    进程与线程
    大小端学习
    联合体和结构体
    内存分配
  • 原文地址:https://www.cnblogs.com/lexus/p/2597759.html
Copyright © 2020-2023  润新知