c-malloc尝试将输入解析为令牌时出现不正确的校验和错误



我试图创建一个shell,但一直遇到错误,

malloc:已释放对象的校验和不正确

在我的代码中,以及测试时的分段错误,是否有可能对此进行修复?我试着调试,但在代码中找不到任何异常,有人能给我指正确的方向吗?

char **getArguments(char line[])
{
/* Pointer to char pointer for storing arguments, initial size is 1 */
char **args = malloc(sizeof(char *));
/* Error handling */
if (args == NULL)
{
fprintf(stderr, "Error: cannot split line.");
exit(EXIT_FAILURE);
}
int count = 0;
/* Try to parse first argument */
char *temp = strtok(line, " tnra");
while (temp != NULL)
{
args[count] = temp;
/* Reallocate more space for next argument */
count++;
char **reallocated = realloc(args, count * sizeof(char *));
/* Error handling */
if (reallocated == NULL)
{
fprintf(stderr, "Error: cannot split line.");
exit(EXIT_FAILURE);
}
else
{
args = reallocated;
}
/* Move to next token */
temp = strtok(NULL, " tnra");
}
/* NULL terminate the array so that we know where's the end */
args[count] = NULL;
return args;
}

count初始化为0,然后使用args[count]进行赋值似乎是个问题。

getArguments()函数最初为参数创建一个单项数组,但随后分配count = 0——这应该是1,因为存在第一个元素。

接下来,代码以count的全长进行赋值。显然,在C中,数组的索引是0length-1,所以my_array[ length ]永远不会正确。

简单地将count初始化为1并将数组索引固定为0偏移量就可以纠正这个问题。

/* Splits the command into arguments */
char **getArguments(char line[])
{
/* Pointer to char pointer for storing arguments, initial size is 1 */
char **args = malloc(sizeof(char *));
/* Error handling */
if (args == NULL)
{
fprintf(stderr, "Error: cannot split line.");
exit(EXIT_FAILURE);
}
int count = 1;                                                       // <-- HERE
/* Try to parse first argument */
char *temp = strtok(line, " tnra");
while (temp != NULL)
{
args[count-1] = temp;                                            // <-- HERE
/* Reallocate more space for next argument */
count++;
char **reallocated = realloc(args, count * sizeof(char *));
/* Error handling */
if (reallocated == NULL)
{
fprintf(stderr, "Error: cannot split line.");
exit(EXIT_FAILURE);
}
else
{
args = reallocated;
}
/* Move to next token */
temp = strtok(NULL, " tnra");
}
/* NULL terminate the array so that we know where's the end */
args[count-1] = NULL;                                           // <-- HERE
return args;
}

输出示例(通过Valgrind(

[user@machine]> valgrind ./run_cmds 
==8173== Memcheck, a memory error detector
==8173== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8173== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8173== Command: ./run_cmds
==8173== 
# /bin/echo foo
foo
# /bin/echo 1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# ==8173== 
==8173== HEAP SUMMARY:
==8173==     in use at exit: 120 bytes in 1 blocks
==8173==   total heap usage: 24 allocs, 23 frees, 3,544 bytes allocated
==8173== 
==8173== LEAK SUMMARY:
==8173==    definitely lost: 0 bytes in 0 blocks
==8173==    indirectly lost: 0 bytes in 0 blocks
==8173==      possibly lost: 0 bytes in 0 blocks
==8173==    still reachable: 120 bytes in 1 blocks
==8173==         suppressed: 0 bytes in 0 blocks
==8173== Rerun with --leak-check=full to see details of leaked memory
==8173== 
==8173== For lists of detected and suppressed errors, rerun with: -s
==8173== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

也许您的代码被指示使用realloc()作为赋值或类似的函数,但更简单的方法是简单地计算参数的数量,将args分配到正确的大小(一次性完成(,从而不进行循环解析重新分配。

相关内容

  • 没有找到相关文章

最新更新