C语言编程技巧--自己写一个动态数组

一、场景

  1. C语言编码,经常需要动态数组处理的情况,比如,我们需要处理一段字符串。现在要将字符串切割返回到 一个列表中。

    /*
    	比如字符串: name=renshaoxia&number=66666&p=890&fjdkf=ddd&dfsjfkd=dd...
    	我希望把这个字符串使用&符号分隔开。而后随时找到任何一个我要的元素。
    	
    	
    	如果我们有个动态数组的的库,如果能够自动把数据弄成如下格式:
    	
    	arr[0] -> "name=renshaoxia"
    	arr[1] -> "number=6666"
    	arr[2] -> "p=809"
    	...
    	
    	瞬间就觉得很好处理了。
    */
    
  2. 使用C语言的库函数切割字符串

    /* 比如,使用,切割字符串,如果我实现了 fv_darray_push 函数,就可以轻松的把字符串放到数组中*/
    
    /*假设str_buf的内容是  "1,2,3,4,5,6,7,8,9,10,11,12,,13,14,15,16,17,18,19,20" */
    char *str = strtok(str_buf,",");
    while(str)
    {
        /*strdup 分配了空间,需要手动做free*/
        fv_darray_push(darray,strdup(str));
        
        str = strtok(NULL,",");
    }
    //.....
    

二、动态数组C语言实现

  1. 我将动态数组的实现放到了 这里
  2. 其实我也是借鉴了awtk代码的源码。awtk源码里面有排序。虽然会方便,但是我任务排序没必要写到这个模块中。
  3. 刚开始的时候,我想到的一些API,写的时候发现和自己想的不一样。最后没有实现。正常的编码中也会经常遇到这种情况吧。
  4. 我写了个例子,分割字符串处理

三、实现过程中遇到问题记录

  1. 调试比较浪费时间的是 fv_darray_push 函数。这个函数是扩展当前数组能存放的指针的大小。使用了realloc函数。

    /*
    	1.使用 realloc 函数 参数指定的大小,就是返回指针指向的真正的大小。最开始以为是追加分配的大小。
    	2.realloc函数,分配的空间,如果是扩大了,那么,之前指针指向空间中的内容不变。超出之前空间的内容没有被初始化。
    	3.不管空间分配是扩大了还是缩小了。之前的那个指针都被释放了。
    	4.realloc 传入的指针必须是malloc分配过的。因为内部会做free。
    */
    ret_t fv_darray_extend(fv_darray_t *darray)
    {
        return_value_if_fail(darray , RET_BAD_PARAMS);
        int size = 8;
        size = darray->size;
    
        darray->elem = realloc(darray->elem,2*size*sizeof(void *));
        if(darray->elem == NULL)
        {
            darray->size = 0;
            darray->elem = NULL;
            return RET_FAIL;    
        }
        memset(darray->elem+sizeof(void*)*darray->size,0x00,sizeof(void *)*size);
        darray->size = 2*size;
        return RET_OK;
    }
    
  2. 我在实现过程中,误以为realloc 是在原来基础上追加空间。所以 一直越界访问。才会一直死机。

  3. fv_darray_pop 函数无法实现。因为弹出之后,就必须释放。释放了弹出元素也没有意义。如果弹出元素但不释放,就要用户操作十分的小心。使用也不方便。

  4. 销毁元素之后,需要将这个指针置空。否则,可能出现double free的死机问题。

四、使用到的技巧整理

  1. 我将 常用到 的for循环 写成了 for_in_range的宏定义,这可以加速编码速度。
  2. 我将 常用到的合法性检测,使用return_value_if_fail宏定义,也可以提升编码速度。
  3. API的前缀可以看出 是属于动态数组模块的API。这样以后使用的时候,方便整理依赖关系。
  4. 还可以优化的地方:
    1. 调试打印,现在使用printf,需要优化。
    2. 内存分配,目前使用calloc,realloc直接分配,需要优化。
    3. free释放的时候,需要先判断是否为空,以及设置为空的操作。也可以使用宏定义优化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值