2013-05-29 23 views
3

的valgrind --tool = MEMCHECK --leak校验=全--show可到达= YES -v ./out如何解决是大小6 alloc'd

==37408== ERROR SUMMARY: 23 errors from 23 contexts (suppressed: 0 from 0) 
==37408== 
==37408== 1 errors in context 1 of 23: 
==37408== Invalid read of size 1 
==37408== at 0x707E: memmove$VARIANT$sse42 (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==37408== by 0x10F08F: strdup (in /usr/lib/system/libsystem_c.dylib) 
==37408== by 0x10000576A: new_node (parser.c:349) 
==37408== by 0x100005E5D: string_literal (parser.c:166) 
==37408== by 0x100001A5D: yyparse (vtl4.y:142) 
==37408== by 0x1000029F1: main (vtl4.y:218) 
==37408== Address 0x100055826 is 0 bytes after a block of size 6 alloc'd 
==37408== at 0x58D3: calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==37408== by 0x100006734: strclip (util.c:35) 
==37408== by 0x100005E4B: string_literal (parser.c:164) 
==37408== by 0x100001A5D: yyparse (vtl4.y:142) 
==37408== by 0x1000029F1: main (vtl4.y:218) 
==37408== 
==37408== 
==37408== 1 errors in context 2 of 23: 
==37408== Invalid read of size 1 
==37408== at 0x67A4: strlen (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==37408== by 0x10F066: strdup (in /usr/lib/system/libsystem_c.dylib) 
==37408== by 0x10000576A: new_node (parser.c:349) 
==37408== by 0x100005E5D: string_literal (parser.c:166) 
==37408== by 0x100001A5D: yyparse (vtl4.y:142) 
==37408== by 0x1000029F1: main (vtl4.y:218) 
==37408== Address 0x100055826 is 0 bytes after a block of size 6 alloc'd 
==37408== at 0x58D3: calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==37408== by 0x100006734: strclip (util.c:35) 
==37408== by 0x100005E4B: string_literal (parser.c:164) 
==37408== by 0x100001A5D: yyparse (vtl4.y:142) 
==37408== by 0x1000029F1: main (vtl4.y:218) 
==37408== 
==37408== ERROR SUMMARY: 23 errors from 23 contexts (suppressed: 0 from 0) 

的块之后0字节new_node(parser.c:349):

struct simpleNode *new_node(JJT jjt,char *node_image){ 
    struct simpleNode *a = malloc(sizeof(struct simpleNode)); 
    if (a==NULL) { 
     yyerror("FUNC[%s]error:Init a new simple error,out of space!",__func__); 
     exit(0); 
    } 
    a->info.astn = jjt; 
    a->info.node_name = jjtNodeName[jjt]; 

    **349**>>a->info.image = strdup(node_image); 
    a->info.already_rendered = cJSON_False; 
    a->parent = NULL; 
    a->firstChild = NULL; 
    a->nextSibling = NULL; 
    return a; 
} 

string_literal(parser.c:166):

struct simpleNode* string_literal(char *str){ 
    //printf("%s node!\n",__func__); 
    char *strc = strclip(str, strlen(str) - 2, 1); 
    //printf("**********strclip:%s\n",strc); 
    **166**>> struct simpleNode* a = new_node(JJTSTRINGLITERAL,strc); 
    //free(strc); 
    free(str); 
    str = NULL; 
    return a; 
} 

strclip(util.c:35)

char * strclip(const char *src, unsigned long n, unsigned long m) { 

    unsigned long len = strlen(src); 
    if (n > len) 
     n = len - m; 
    if (m > len) 
     return NULL ; 
    const char * right_start = src + m; 

    **35**<< char *q = (char *) calloc(n, sizeof(char)); 

    strncpy(q, right_start, n); 

    return q; 
} 

我很长一段时间没有找到问题的根源学习,请大家帮我

回答

6

strclip()strncpy()是你的问题的原因!;

如果源的长度大于num,则不会在目的地末尾附加任何空字符。因此,在这种情况下,目标不应被视为空终止的C字符串(因为它会溢出)。

由于您使用calloc()无论如何要获得填充零的内存,所有你需要做的就是分配一个额外的字符,不会被覆盖;

char *q = (char *) calloc(n + 1, sizeof(char)); 
strncpy(q, right_start, n); 

这将使缓冲区的最后一个字符为零,所以你有一个保证的字符串终止。

+2

请勿使用'strncpy',[strncpy不是strcpy的安全版本](http://stackoverflow.com/questions/2114896/why-is-strlcpy-and-strlcat-considered-to-是不安全的)。做到这一点的适当的,最快的方法是malloc,memcpy,然后是手动空终止。 – Lundin

相关问题