2012-07-10 64 views
0

我正在开发一个程序,它是一种设计用于在各种服务器上运行的心跳。下面转载的这个函数检索“friends”列表,并为列表中的每个“friend”执行握手操作(通过ping_and_report,未显示)。strtok返回的字符串太多

问题是,在第一次调用这个例程时,strtok_r似乎返回比源代码中存在的字符串更多的字符串,并且我还无法确定原因。代码:

void pingServerList(int dummy) { 
    char *p ; 
    char *my_friends ; 
    char *nextSvr, *savePtr ; ; 
    char *separators = ",; \t" ; 
    server_list_t *ent = NULL ; 
    static long round_nbr = 0 ; 
    unsigned int len ; 
    time_t now ; 
    char message[4096] ; 
    char *hex ; 

    round_nbr++ ; 
    p = get_server_list() ; 
    if (p) { 
     len =strlen(p) ; 
     my_friends = malloc(len+1) ; 
     strncpy(my_friends, p, len) ; 
     } 
    nextSvr = strtok_r(my_friends, separators, &savePtr) ; 
    while (nextSvr) { 
     // Ensure that nobody messes with nextSvr. . . 
     char *workSvr = malloc(strlen(nextSvr) + 1) ; 
     strcpy(workSvr, nextSvr) ; 
     if (debug) { 
      len = strlen(workSvr) * 2 + 3 ; 
      hex = malloc(len) ; 
      get_hex_val(workSvr, hex, len) ; 
      write_log(fp_debug 
        , "Server: %s (x'%s')" 
        , workSvr, hex) ; 
      free(hex) ; 
      } 
     ping_and_report(workSvr, round_nbr) ; 
     free(workSvr) ; 
     nextSvr = strtok_r(NULL, separators, &savePtr) ; 
     } 

......我认为在这一点上并不太复杂。而且我看不出有什么空间可以用这些价值观去分析。但是,日志文件在这里揭示了问题:

2012-07-09 23:26 Debug activated... 
2012-07-09 23:26 get_server_list() returning velmicro, stora-2 (x'76656C6D6963726F2C2073746F72612D32') 
2012-07-09 23:26 Server: velmicro (x'76656C6D6963726F') 
2012-07-09 23:26 Server: stora-2 (x'73746F72612D32') 
2012-07-09 23:26 Server: re (x'726519') 

疯狂的事情是,(在从代码的几个处决至少),这只会在第一次呼叫失败。呼叫2-n(其中n在数百)不会出现这个问题。

做你们任何人都明白我明显缺少的东西吗? (顺便说一句:失败正好与Linux版本四种不同的系统以同样的方式。)

+0

如果在调用get_server_list()后'p'为NULL,'my_friends'是传递给'strtok_r()'的未初始化指针。 – hmjd 2012-07-10 10:27:07

+0

'my_friends = strdup(p)' – fork0 2012-07-10 10:29:52

+0

同样为每个“朋友”/地址填写。并且你泄漏为my_friends分配的内存 – fork0 2012-07-10 10:31:41

回答

3

当你写这个

strncpy(my_friends, p, len) ; 

你是不是保证my_friends以\ 0

试结束

strncpy(my_friends, p, len)[len-1] = '\0'; 

alt。使用calloc分配my_friends

+0

+1。我想你找到了确切的错误地方! @Dennis - strncpy()函数最多将n个字符从s2复制到s1中。如果s2长度小于n个字符,则s1的其余部分用'\ 0'字符填充。否则,s1不会终止。在这种情况下,len等于s2中的字符数,所以s1不会以NULL结尾。 – Jay 2012-07-10 10:38:48

+0

'strncpy(my_friends,p,len)[len-1]'是一个非常难看的代码结构。这不是[code golf](http://codegolf.stackexchange.com) - 使用'my_friends [len-1] ='\ 0';' – ugoren 2012-07-10 10:46:55

+0

或只是'my_friends = strdup(p);' – ugoren 2012-07-10 10:49:37