【发布时间】:2015-05-23 04:48:46
【问题描述】:
我正在编写一个 shell。当我像这样cat /dev/urandom | valgrind ./myshell 执行它来运行一些测试并查看我是否没有任何段错误或其他错误时,valgrind 有时会告诉我在函数my_wordcpy 中有一个Invalid Write 在这一行@987654325 @
它不会每次都发生,但确实会发生,我就是不明白为什么。这是我的代码:
static int count_words(char *str, char *sep)
{
int quote;
int words;
int i;
i = -1;
if (count_quotes(str) == -1)
return (0);
words = 0;
quote = 0;
while (str[++i] != '\0')
{
if (str[i] == '"')
{
if (quote == 0)
quote = 1;
else
quote = 0;
}
if (quote == 0
&& (is_cinside(sep, str[i]) == 0 && str[i] != '\t' &&
(is_cinside(sep, str[i + 1]) == 1 ||
str[i + 1] == '\t' || str[i + 1] == '\0')))
++words;
}
return (words);
}
static int my_wordlen(char *str, int *i, char *sep)
{
int quote;
int j;
j = 0;
quote = 0;
while (str[++(*i)] != '\0')
if (str[*i] == '"' && quote == 0)
quote = 1;
else if (quote == 1 || (quote == 0 && is_cinside(sep, str[*i]) == 0 &&
str[*i] != '\t'))
{
++j;
if ((quote == 1 && str[*i + 1] == '"') ||
(quote == 0 && (is_cinside(sep, str[*i + 1]) == 1 ||
str[*i + 1] == '\t' ||
str[*i + 1] == '\0')))
{
if (quote == 1 && str[*i + 1] == '"')
++(*i);
return (j);
}
}
return (-1);
}
static char *my_wordcpy(char *tab, char *str, int *i, char *sep)
{
int quote;
int j;
j = -1;
quote = 0;
while (str[++(*i)] != '\0')
if (str[*i] == '"' && quote == 0)
quote = 1;
else if (quote == 1 || (quote == 0 &&
is_cinside(sep, str[*i]) == 0 && str[*i] != '\t'))
{
tab[++j] = str[*i]; /* here is the invalid write. */
if ((quote == 1 && str[*i + 1] == '"') ||
(quote == 0 && (is_cinside(sep, str[*i + 1]) == 1 ||
str[*i + 1] == '\t' || str[*i + 1] == '\0')))
{
if (quote == 1 && str[*i + 1] == '"')
++(*i);
tab[++j] = '\0';
return (tab);
}
}
return (NULL);
}
char **my_quotetowordtab(char *str, char *sep)
{
char **tab;
int words;
int i;
int j;
int k;
i = -1;
j = -1;
k = -1;
if (str == NULL)
return (NULL);
words = count_words(str, sep);
if ((tab = malloc(sizeof(char *) * (words + 1))) == NULL)
return (NULL);
while (++i < words)
{
if ((tab[i] = malloc(sizeof(char) * (my_wordlen(str, &j, sep) + 1)))
== NULL)
return (NULL);
tab[i] = my_wordcpy(tab[i], str, &k, sep);
}
tab[i] = NULL;
return (tab);
}
【问题讨论】:
-
您能否在您的代码(断言)中放置一个 if 案例,以确保在递增后
j中的值以及*i也是有效的并且仍在tab内和str数组?写入无效的唯一方法是如果j超出范围,tab是垃圾,*i超出范围,或者str是垃圾。 -
好吧,我不认为它超出了界限,因为我用 my_wordlen 函数的返回分配了正确的数量(这是相同的函数,只是它不复制,只是计数字符),我还尝试了更多的 malloc(+ 1000)以扩大范围,但它不起作用。我仍然有内存损坏崩溃。标签是垃圾是什么意思?
-
tab asgarbage 将是一个错误的指针传递给函数,但如果上面的代码确实是进入函数的唯一方法,这种可能性非常低。
-
对
j进行 if 检查将 100% 解决索引错误的问题,但我仍然认为您对引用有问题,如下所述。 -
是的,但问题是我受到编码风格的限制,我不能向函数发送超过 4 个参数,而我已经有 4 个。所以我真的不明白如何在不发送标签长度的情况下进行良好的检查:-/