首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

诸位大神帮忙修改一下程序,感激不尽。

2013-06-25 
各位大神帮忙修改一下程序,感激不尽。急!程序实现功能:1、连接数据库dnsdata,从表domain_name中查询待检测域

各位大神帮忙修改一下程序,感激不尽。急!
程序实现功能:
1、连接数据库dnsdata,从表domain_name中查询待检测域名(字符串)
2、查询出的域名去和表million_doamin_name表中的域名比较,计算相似度,然后对得到的相似度排序,得到与源字符串最相似的,输出这个对应关系
3、计算相似度用的算法是编辑距离,排序是堆排序,我用一个结构体保存目标域名和相似度的对应关系
4、自己写了一个函数parse_name用来分割域名,只提取二级域名,如www.baidu.com中的baidu
问题:
1、程序运行到parse_name时会出现段错误,而这个函数单独拿出来测试可以通过
2、感觉这个程序问题不少,但是别人急着要使用这个程序做后续的工作,求大神们帮我提以下修改方案,我几乎把分都用了,希望能解决问题(个人编程能力较弱)

#include <stdlib.h>
#include <stdio.h>
#include <mysql/mysql.h>
#include <syslog.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
MYSQL mysql;

struct domain
{
    char *name;
    float data;
};

void sift(float a[], int i, int n)
{
    int child;
    float tmp;
    for (tmp = a[i]; n >= 2 * i; i = child)
    {
        child = 2 * i;
        if (child != n && a[child + 1] < a[child])
        {
            child++;
        }
        if (tmp > a[child])
        {
            a[i] = a[child];
        }
        else break;
    }
    a[i] = tmp;
}

void heapsort(float a[], int n)
{
    int i;
    float tmp;
    for (i = n / 2; i >= 1; i--)
    {
        sift(a, i, n);
    }
    for (i = n; i >= 2; i--)
    {
        tmp = a[1];
        a[1] = a[i];
        a[i] = tmp;

        sift(a, 1, i-1);
    }
}

int min(int a,int b,int c)
{
    if(a<b&&a<c)
        return a;
    else if(b<a&&b<c)
        return b;
    else
        return c;
}
int max(int x,int y)
{
    int z;
    if(x>y)
    {
        z=x;
    }
    else
    {
        z=y;
    }
    return z;
}

int distance(char *strA,char *strB)
{
    int m=strlen(strA);
    int n=strlen(strB);


    int d[m+1][n+1];
    int i,j,x,y,z;
    for(i=0; i<=m; i++)
        d[i][0] = i;
    for(j=1; j<=n; j++)
        d[0][j] = j;
    for(i=1; i<=m; i++)
        for(j=1; j<=n; j++)
        {
            x = d[i-1][j]+1;
            y = d[i][j-1]+1;
            if(strA[i] == strB[j])
                z = d[i-1][j-1];
            else
                z = d[i-1][j-1]+1;
            d[i][j] = min(x,y,z);
        }
    return d[m][n];
}

void parse_name(char* sour,char *dest)
{
    char seps[] = ".";
    char* token;
    int j = 0;
    char* arr[10];

    token = strtok(sour, seps);
    while(token != NULL)
    {
        arr[j] = (char*)malloc(512);
        strcpy(arr[j], token);
        j++;
        token = strtok(NULL, seps);
    }
    dest= arr[j - 2];
}

void doquerysimilar(char str[])
{
    int i,k,row;
    MYSQL_ROW m_row;
    MYSQL_RES *m_res;
    char sql[1024];
    char dname[128]="";
    char pattern[128]="";

    parse_name(str,dname);
    sprintf(sql,"select Idomain from million_domain_name order by id limit 0,100");
    if(mysql_query(&mysql,sql) != 0)
    {
        fprintf(stderr, "mysql_query err: %s",mysql_error(&mysql));
    }
    m_res = mysql_store_result(&mysql);
    row = mysql_num_rows(m_res)+1;
    float sim[row];
    struct domain dom[row];
    if(m_res==NULL)
    {
        fprintf(stderr, "get result err: %s",mysql_error(&mysql));
    }

    for(i=0; i<row; i++)
    {
        m_row = mysql_fetch_row(m_res);
        if(m_row!=NULL)
        {
            dom[i].name=m_row[0];


            parse_name(m_row[0],pattern);
            k=distance(dname,pattern);
            sim[i]=1-(float)k/max(strlen(dname),strlen(pattern));
            dom[i].data=sim[i];

        }
    }
    heapsort(sim,row);
    for(i=0; i<row; i++)
    {
        if(dom[i].data==sim[0]&&sim[0]>0.7&&sim[0]<1.0)
        {
            printf("%s is similar to %s\n",str,dom[i].name);
        }
    }

    mysql_free_result(m_res);

}

void doQuery()
{
    int i,row;
    MYSQL_ROW m_row;
    MYSQL_RES *m_res;
    char sql[1024];

    sprintf(sql,"select domain from domain_name order by id limit 0,30000");
    if(mysql_query(&mysql,sql) != 0)
    {
        fprintf(stderr, "mysql_query err: %s",mysql_error(&mysql));
    }
    m_res = mysql_store_result(&mysql);
    row = mysql_num_rows(m_res)+1;


    if(m_res==NULL)
    {
        fprintf(stderr, "get result err: %s",mysql_error(&mysql));
    }


    for(i=0; i<row; i++)
    {
        m_row = mysql_fetch_row(m_res);
        if(m_row!=NULL)
            doquerysimilar(m_row[0]);
    }
    mysql_free_result(m_res);

}

int main()
{
    char host[32] = "localhost";
    char user[32] = "root";
    char passwd[32] = "123";
    char db[32] = "dnsdata";
    if( mysql_init(&mysql) == NULL )
    {
        fprintf(stderr,"Init mysql err!");
        return 0;
    }
    if (mysql_real_connect(&mysql,host,user,passwd,db,0,NULL,0) == NULL)
    {
        fprintf(stderr,"Connect to mysql Error:%s!",mysql_error(&mysql));
        return 0;
    }
    else
    {
        puts("Connect to mysql success!");
    }

    doQuery();
    mysql_close(&mysql);
    return 0;


}


[解决办法]
下面是你写的parse_name函数的解析:

该函数的参数没有参数检查就直接使用并且该函数不是static的,那我认为该函数是外部接口,也有风险存在
while(token != NULL)
    {
        arr[j] = (char*)malloc(512);   在这里分配了内存空间,程序效率很低
        strcpy(arr[j], token);         在这里又copy,效率又降低。
        j++;
        token = strtok(NULL, seps);
    }
    dest= arr[j - 2];       没有释放上面分配的空间,出现严重的内存泄露。




[解决办法]
在不改变你代码逻辑的情况下,我认为这样实现更好一些:

#include <stdio.h>
#include <assert.h>
#include <string.h>

#define SLD_SHIFT 2
#define SLD_MAX 512
#define SLD_SEPARATOR '.'
int parse_name(const char *sour,char *dest)
{
int len = 0; 
int i = 0;
const char *pch = NULL; 
assert(sour); 
assert(dest); 

len = strlen(sour); 
pch = &sour[len]; 
for(i = 0; i++ < SLD_SHIFT; ) {
while((SLD_SEPARATOR != *pch) && (sour != pch)) {
pch--;
}
if(sour == pch) {
break; 
}
if(SLD_SHIFT > i) {
while(SLD_SEPARATOR == *--pch) {
/* no thing */
}
}
}
if(SLD_SHIFT > i) {
return 1;   /* 没找到分隔符 */
}

if(sour != pch) {
pch += 1; 
}

while(SLD_SEPARATOR != (*dest++ = *pch++)) {

}
dest--; 
*dest = '\0'; 

return 0; 
}

热点排行
Bad Request.