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;
}
我研究了很久没找到问题的根本原因,请帮帮我!
答案 0 :(得分:6)
strclip()
中的{p> strncpy()
是导致问题的原因;
如果source长于num ,则不会在目标末尾隐式附加空字符。因此,在这种情况下,destination不应被视为空终止的C字符串(读取它会溢出)。
由于你无论如何使用calloc()
来获取内存都是零,所以你需要做的就是分配一个不会被覆盖的额外字符;
char *q = (char *) calloc(n + 1, sizeof(char));
strncpy(q, right_start, n);
这会将缓冲区的最后一个字符保留为零,因此您可以保证字符串的终止。