【问题标题】:How to solve is 0 bytes after a block of size 6 alloc'd如何解决是分配大小为 6 的块后的 0 字节
【发布时间】:2013-05-29 09:52:47
【问题描述】:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes -v ./out

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

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

研究了半天没找到问题的根源,请大家帮帮我!

【问题讨论】:

    标签: c valgrind


    【解决方案1】:

    strclip() 中的strncpy() 是您的问题的原因;

    如果 source 长于 num,则不会在目标末尾隐式附加空字符。因此,在这种情况下,destination 不应被视为以 null 结尾的 C 字符串(这样读取它会溢出)。

    由于您无论如何都在使用calloc() 来使内存填充零,因此您需要做的就是分配一个不会被覆盖的额外字符;

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

    这将使缓冲区的最后一个字符为零,因此您可以保证字符串的终止。

    【讨论】:

    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 2023-03-03
    • 2015-03-17
    • 1970-01-01
    • 2018-08-21
    • 2012-06-07
    • 1970-01-01
    • 2019-11-25
    相关资源
    最近更新 更多