我正在运行valgrind的代码
int fun(char* str) {
char* prt1;
char* ptr2;
char sstr[20];
strcpy(sstr, "\0");
ptr1 = str;
ptr2 = sstr;
while (((isspace(*ptr1)) || (iscntrl(*ptr1))) && (*ptr1 != '\0'))
ptr1++;
while (*ptr1 != '\0')
*ptr2++ = *ptr1++;
while (((isspace(*(ptr2 - 1))) || (iscntrl(*(ptr2 - 1)))) && (ptr2 > str))
ptr2++;
*ptr2 = '\0' strcpy(str, (S8*)sstr);
return (strlen(ptr1));
}
收到此错误 使用大小为8的未初始化值 换行
while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) &&
(ptr2 > str))
如果我在分配指针之前进行NULLP
检查,则错误消失
if (ptr1 != NULLP && ptr2 != NULLP) {
ptr1 = str;
ptr2 = sstr;
}
是否存在Valgrind代码错误或应包括检查?
感谢您的帮助。
答案 0 :(得分:3)
没有检查NULLP是完全错误的,实际上调用了未定义的行为,因为那时指针没有被初始化。
真正的问题是,当你第一次进入循环
while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) && (ptr2 > str))
你检查复制的最后一个字符,如果它是一个空格或控制字符,你递增ptr2
,现在你检查第一个字符你从未初始化。
(抛开这样一个事实,即你没有复制任何字符的情况也是错误的。然后isspace(*(ptr2-1))
也会调用UB)
如果你想修剪sstr
(是这样吗?),你的循环应该是
while ( ptr2 > sstr && ( isspace (ptr2[-1]) || iscntrl (ptr2[-1]) ) )
ptr2--;
请注意差异:
ptr2
与sstr
进行比较,而不是str
进行比较,然后先执行此操作,以便在isspace()
<时不执行iscntrl()
和ptr2 == sstr
/ LI>
ptr2--
代替ptr2++
答案 1 :(得分:1)
我想如果你改变这一行:
while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) && (ptr2 > str))
到此:
while ((ptr2 > str) && ((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))))
你不会得到错误。看起来你可能正在阅读之前
str
的开头,因为您的支票ptr2 > str
将在此之后发生
解引用。将此检查移至条件的开头允许
它会短路。