編程基礎及技巧

避免對空指針進行賦值操做時內存崩潰方法:數據庫

char netdb[1024] = {0};定義數組常量數組

char *netdebug = netdb;把數組指針賦值給字符串指針,這樣字符串指針就不是空指針了,避免了空指針操做。函數

 

 

 

fseek(fp, 0, 2);debug

acklen = ftell(fp);指針

fseek(fp, 0, 0);       求文件指針的指向的文件的大小調試

/*執行結果寫進ackuf */server

if((fgets(ackbuf, acklen, fp)) ==NULL )    fgets函數一次只能讀取一行內存

{rem

   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);

相關文章
相關標籤/搜索