首页 > 代码库 > 编程基础及技巧

编程基础及技巧

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

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\n", tmp);

fprintf(stderr, "222222222222222222222222:%d\n", 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, "\r\n");

    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, "\r\n");

        assert(tmp);

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

        break;

    case ‘3‘:

        /* traceroute */

        tmp = strtok(NULL, "\r\n");

        assert(tmp);

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

        break;

    case ‘4‘:

        /* nmap */

        tmp = strtok(NULL, "\r\n");

        assert(tmp);

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

        break;

    default :

        /* other error!! */

        ackstatus = ERR_CLIREQ;

        goto Err;

    }

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

tmp = strtok((char *)reqbuf, "\r\n");

    cmdnum = atoi(tmp);

 

    /* 容错处理 */

    if(cmdnum < 0 || cmdnum >4)

    {

         ackstatus = ERR_CLIREQ;

         goto Err;

    }

 

    /* 命令参数 */

    tmp = strtok(NULL, "\r\n");

    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, "\r\n");        不需要给tmp提前分配内存,因为tmp只是和strtok指向同一个内存空间。

 

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

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

        char test[] = "192.168.51.206\r\n21\r\nftp\r\n123456\r\nDIRECTORY\r\n\r\n";

        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\n",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\n", 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\n", cmdline);

        retval = iw_db_select(cmdline, res);

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

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

        char *res = NULL;

        int retval = 0;

        DEBUGLOG(IW_LOG_MAINBRANCE, DEBUG, "keyname=%s,endtime=%s,remark=%s\n", 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\n", cmdline);

        retval = iw_db_select(cmdline, &res);

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

 

编程基础及技巧