zoukankan      html  css  js  c++  java
  • 编程基础及技巧

    避免对空指针进行赋值操作时内存崩溃方法:

    char netdb[1024] = {0};定义数组常量

    char *netdebug = netdb;把数组指针赋值给字符串指针,这样字符串指针就不是空指针了,避免了空指针操作。

    fseek(fp, 0, 2);

    acklen = ftell(fp);

    fseek(fp, 0, 0);       求文件指针的指向的文件的大小

    /*执行结果写进ackuf */

    if((fgets(ackbuf, acklen, fp)) ==NULL )    fgets函数一次只能读取一行

    {

       ackstatus = ERR_CLIREQ;

       goto Err;

    }

    调试语句,加在你认为可能出错的地方,例如:

    fprintf(stderr, "00000000000000000000:%s ", tmp);

    fprintf(stderr, "222222222222222222222222:%d ", acklen);

    if(!strncmp(tmp, "0", strlen(tmp))) 判断字符串是否是0,这种用法很繁琐,可以用下面的指令:

    if(tmp[0] == '0')

        char netto[1024] = {0};

        char *nettool = netto;

    char *nettooldef = netto;两个字符串指针指向的是同一个内存地址,无论是对nettool操作还是对nettooldef操作,都是对同一个内存地址进行操作。还是没有避免混淆。

    正确用法:

    char netto[1024] = {0};

        char nettodef[1024] = {0};

        char *nettool = netto;

    char *nettooldef = nettodef;

    strncat("ping -c 3", tmp, strlen(tmp));这种用法是错误的,extern char *strncat(char *dest,char *src,int n);  dest是一个指针变量,代表内存地址,不应该是常量。正确用法如下:

    char ping[20] = "ping -c 3";

    strncat(ping, tmp, strlen(tmp));

    fseek(fp, 0, 2);

    acklen = ftell(fp);

    fseek(fp, 0, 0);

    ackbuf = (char *)malloc(acklen);

    /*执行结果写进ackuf */

    if((fread(ackbuf, 1, acklen, fp)) != acklen )     这样管道获取acklen是错误的。解决方法如下

    while(!feof(fp) && (++acount_buf))

        {

            /* strlen入参不能为空指针!!!!!!!!!!!!!!!!!,故改用acount_buf */

            ackbuf = (unsigned char *)realloc(ackbuf, acount_buf * BUF_SIZE);

            if(!ackbuf)

            {

                ackstatus = ERR_CLIREQ;

                goto Err;

            }

            fread(ackbuf + strlen(ackbuf), sizeof(char), BUF_SIZE, fp);}   第一次只是给ackbuf分配了内存空间,但是没有赋值,而strlen求的是实际的字符串长度,因此strlen(ackbuf)=0.

       /* 标志位 */

        tmp = strtok((char *)reqbuf, " ");

        switch(tmp[0])

        {

        case '0':

            /* netstat */

            snprintf(cmdline, sizeof(cmdline), "%s", NETSTAT_CMD);

            break;

        case '1':

            /* arp */

            snprintf(cmdline, sizeof(cmdline), "%s", ARP_CMD);

            break;

        case '2':

            /* ping */

            tmp = strtok(NULL, " ");

            assert(tmp);

            snprintf(cmdline, sizeof(cmdline), "%s%s", PING_CMD, tmp);

            break;

        case '3':

            /* traceroute */

            tmp = strtok(NULL, " ");

            assert(tmp);

            snprintf(cmdline, sizeof(cmdline), "%s%s", TRACEROUTE_CMD, tmp);

            break;

        case '4':

            /* nmap */

            tmp = strtok(NULL, " ");

            assert(tmp);

            snprintf(cmdline, sizeof(cmdline), "%s%s", NMAP_CMD, tmp);

            break;

        default :

            /* other error!! */

            ackstatus = ERR_CLIREQ;

            goto Err;

        }

    这段程序很是繁琐,修改如下:

    tmp = strtok((char *)reqbuf, " ");

        cmdnum = atoi(tmp);

        /* 容错处理 */

        if(cmdnum < 0 || cmdnum >4)

        {

             ackstatus = ERR_CLIREQ;

             goto Err;

        }

        /* 命令参数 */

        tmp = strtok(NULL, " ");

        snprintf(cmdline, sizeof(cmdline), "%s%s", cmdbuf[cmdnum], tmp ? tmp : "");

        snprintf(cmdline, sizeof(cmdline), "%s%s", cmdbuf[cmdnum], tmp ? tmp : null);

    编译出错,null没有内存地址,snprintf出错。修改如下:

        snprintf(cmdline, sizeof(cmdline), "%s%s", cmdbuf[cmdnum], tmp ? tmp : "");

    char *tmp = NULL;

    tmp = strtok((char *)cmdline, " ");        不需要给tmp提前分配内存,因为tmp只是和strtok指向同一个内存空间。

    调试语句的使用技巧,使用#if 1   #endif 1:

    #if 1(0表示永远都不会成立的一个条件,这样这段代码就不会编译了,1表示永远都成立的条件)

            char test[] = "192.168.51.206 21 ftp 123456 DIRECTORY ";

            reqbuf = (char *)test;

    #endif

    makecert.c:

    struct iw_key_struct

    {

            char crtname[64];

            char commoname[64];

            char country[4];

    …….

    }

    …..

    tmp=China;

    sprintf(keystr->country,"%s ",tmp);

    程序执行错误,修改char country[10]之后,没有问题了。使用sprintf时,格式化数据大小必须小于字符缓冲区大小。

    #define MAKEKEYPATH "/home/xiachengjiao/nnba/nnba/mise/calls/engine/key/"

    snprintf(cmdline, sizeof(cmdline), "mkdir %sdemoCA 1>/dev/null 2>&1", MAKEKEYPATH);

    retval = iw_system(cmdline);

    指令执行错误,因为/engine/key/demoCA/之前不存在,所以mkdir需要加参数-p。正确写法:

    snprintf(cmdline, sizeof(cmdline), "mkdir –p %sdemoCA 1>/dev/null 2>&1", MAKEKEYPATH);

    snprintf(cmdline, sizeof(cmdline), "select keyname from server.ww_cert_t where keyname='%s'", keyname);

    snprintf的用法是挺巧妙的,如上。

            char **res = NULL;

            int retval = 0;

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "keyname=%s,endtime=%s,remark=%s ", keyname, endtime, remark);

            /* 判断数据库表中证书名称是否重复 */

            snprintf(cmdline, sizeof(cmdline), "select keyname from server.ww_cert_t where keyname='%s'", keyname);

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "cmdline=%s ", cmdline);

            retval = iw_db_select(cmdline, res);

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "retval=%d,*res=%s ",  retval,* res);

    程序段错误,下面程序正确的。

            char *res = NULL;

            int retval = 0;

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "keyname=%s,endtime=%s,remark=%s ", keyname, endtime, remark);

            /* 判断数据库表中证书名称是否重复 */

            snprintf(cmdline, sizeof(cmdline), "select keyname from server.ww_cert_t where keyname='%s'", keyname);

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "cmdline=%s ", cmdline);

            retval = iw_db_select(cmdline, &res);

            DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "retval=%d,res=%s ",  retval, res);

    如果有一天我们淹没在茫茫人海中,庸碌一生,那一定是我们没有努力活得丰盛
  • 相关阅读:
    spring boot启动原理
    Minor GC ,Full GC 触发条件是什么?
    Redis分布式锁的正确实现方式Jedis客户端实现方式总结
    JVM命令总结
    InnoDB中B+树总结
    ThreadPoolExecutor 优先级的线程池
    锁的概述
    Deadlock Troubleshooting, Part 1
    Deadlock Troubleshooting, Part 3
    大型网站数据库优化和故障跟踪与排查(下篇)
  • 原文地址:https://www.cnblogs.com/xiachj/p/4112101.html
Copyright © 2011-2022 走看看