wprintf 会在 valgrind 中导致 "conditional jump or move depends on uninitialised value(s)" 吗?
Does wprintf cause "conditional jump or move depends on uninitialised value(s)" in valgrind?
我正在尝试编写解决以下问题的函数(这无关紧要,我描述它是为了描述后面的代码):
给定一个单词和一个规则的形式:"lhs->rhs" 其中单词= lhs ^ suffix,输出rhs ^ suffix,例如:
如果单词是 "input" 并且规则是 "in->out" 函数将 return 单词 "output",如果规则不能用于单词则为 NULL .
虽然有一个转折点:"lhs" 可能还包含数字变量(除了字母),例如。 G。 “01->10”,在这种情况下,当用于 "niput" 时,该规则会将 "niput" 转换为 "input"(因此数字对应于位于特定位置的字母)。
代码如下:
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_WORD_SIZE 101
wchar_t *transform_by_rule(wchar_t *word, wchar_t *lhs, wchar_t *rhs)
{
int i;
long int wint;
int lhs_len = wcslen(lhs);
int rhs_len = wcslen(rhs);
int word_len = wcslen(word);
// Initial check - does lhs fit to word
if (word_len < lhs_len)
return NULL;
for (i = 0; i < lhs_len; i++)
{
if (iswdigit(lhs[i]))
continue;
else
{
if (lhs[i] != word[i])
return NULL;
}
}
wchar_t *result =
malloc((rhs_len + 1) * sizeof(wchar_t));
wchar_t int_wchar_map[10];
for (i = 0; i < lhs_len; i++)
{
if (iswdigit(lhs[i]))
{
wint = lhs[i] - L'0';
int_wchar_map[wint] = word[i];
}
}
for (i = 0; i < rhs_len; i++)
{
if (iswdigit(rhs[i]))
{
wint = rhs[i] - L'0';
result[i] = int_wchar_map[wint];
}
else
{
result[i] = rhs[i];
}
}
return result;
}
int main()
{
wchar_t word[MAX_WORD_SIZE];
wchar_t lhs[MAX_WORD_SIZE];
wchar_t rhs[MAX_WORD_SIZE];
wscanf(L"%ls", word);
wscanf(L"%ls", lhs);
wscanf(L"%ls", rhs);
wchar_t *result = transform_by_rule(word, lhs, rhs);
if (result != NULL)
{
wprintf(L"%ls\n", result); // line 67
free(result);
}
else
{
puts("Rule doesn't fit to word.");
}
return 0;
}
问题来了。当运行在valgrind下输入"a"(word),"a"(lhs),"b"(rhs)时,valgrind输出错误:
==6094== Conditional jump or move depends on uninitialised value(s)
==6094== at 0x4C30E19: wcslen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6094== by 0x4E8C3F6: vfwprintf (in /usr/lib64/libc-2.20.so)
==6094== by 0x4EA7448: wprintf (in /usr/lib64/libc-2.20.so)
==6094== by 0x4009AA: main (main.c:67)
我没有发现我的代码有任何问题。这是 wprintf() 的问题吗?
result
在 return 从 transform_by_rule()
开始之前不是零终止的。因此,当对其 return 值调用 wprintf()
时,wprintf()
可能会越界读取,因为它可能不会在分配的内存块中遇到终止宽字符。
使用 wchar_t *result = calloc(rhs_len + 1, sizeof(wchar_t));
,如果您确定没有在 transform_by_rule()
.
内写越界,您将自动获得正确终止的字符串
我正在尝试编写解决以下问题的函数(这无关紧要,我描述它是为了描述后面的代码):
给定一个单词和一个规则的形式:"lhs->rhs" 其中单词= lhs ^ suffix,输出rhs ^ suffix,例如:
如果单词是 "input" 并且规则是 "in->out" 函数将 return 单词 "output",如果规则不能用于单词则为 NULL .
虽然有一个转折点:"lhs" 可能还包含数字变量(除了字母),例如。 G。 “01->10”,在这种情况下,当用于 "niput" 时,该规则会将 "niput" 转换为 "input"(因此数字对应于位于特定位置的字母)。
代码如下:
#include <wchar.h>
#include <stdlib.h>
#include <stdio.h>
#define MAX_WORD_SIZE 101
wchar_t *transform_by_rule(wchar_t *word, wchar_t *lhs, wchar_t *rhs)
{
int i;
long int wint;
int lhs_len = wcslen(lhs);
int rhs_len = wcslen(rhs);
int word_len = wcslen(word);
// Initial check - does lhs fit to word
if (word_len < lhs_len)
return NULL;
for (i = 0; i < lhs_len; i++)
{
if (iswdigit(lhs[i]))
continue;
else
{
if (lhs[i] != word[i])
return NULL;
}
}
wchar_t *result =
malloc((rhs_len + 1) * sizeof(wchar_t));
wchar_t int_wchar_map[10];
for (i = 0; i < lhs_len; i++)
{
if (iswdigit(lhs[i]))
{
wint = lhs[i] - L'0';
int_wchar_map[wint] = word[i];
}
}
for (i = 0; i < rhs_len; i++)
{
if (iswdigit(rhs[i]))
{
wint = rhs[i] - L'0';
result[i] = int_wchar_map[wint];
}
else
{
result[i] = rhs[i];
}
}
return result;
}
int main()
{
wchar_t word[MAX_WORD_SIZE];
wchar_t lhs[MAX_WORD_SIZE];
wchar_t rhs[MAX_WORD_SIZE];
wscanf(L"%ls", word);
wscanf(L"%ls", lhs);
wscanf(L"%ls", rhs);
wchar_t *result = transform_by_rule(word, lhs, rhs);
if (result != NULL)
{
wprintf(L"%ls\n", result); // line 67
free(result);
}
else
{
puts("Rule doesn't fit to word.");
}
return 0;
}
问题来了。当运行在valgrind下输入"a"(word),"a"(lhs),"b"(rhs)时,valgrind输出错误:
==6094== Conditional jump or move depends on uninitialised value(s)
==6094== at 0x4C30E19: wcslen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==6094== by 0x4E8C3F6: vfwprintf (in /usr/lib64/libc-2.20.so)
==6094== by 0x4EA7448: wprintf (in /usr/lib64/libc-2.20.so)
==6094== by 0x4009AA: main (main.c:67)
我没有发现我的代码有任何问题。这是 wprintf() 的问题吗?
result
在 return 从 transform_by_rule()
开始之前不是零终止的。因此,当对其 return 值调用 wprintf()
时,wprintf()
可能会越界读取,因为它可能不会在分配的内存块中遇到终止宽字符。
使用 wchar_t *result = calloc(rhs_len + 1, sizeof(wchar_t));
,如果您确定没有在 transform_by_rule()
.