因此,我正在为一个简单的shell编写一个C程序。不是很难,但我遇到了一个很奇怪的问题,我无法解释。我试图在一个结构中创建一个二维数组来表示一个命令及其参数。例如,对于命令"ls -l“,我希望第一个元素是"ls”,第二个元素是"-l“。似乎工作得很好,除了malloc将"ls“改为"ms”。对于其他命令也是如此,第一个字符是递增的;不是在malloc之前,而是紧跟在malloc之后。
这就是有问题的代码块……
printf ("PRE MALLOC: %c\n", ret_val->args[0][0]);
printf ("[0] %p\n", ret_val->args[0]);
ret_val->args[1] = (char*) malloc ((3) * sizeof (char));
printf ("[0] %p\n", ret_val->args[0]);
printf ("[1] %p\n", ret_val->args[1]);
printf ("POST MALLOC: %c\n", ret_val->args[0][0]);我要做的就是分配一个3( -l + null )字符数组来保存args1中的"-l“。这些都不是真正的硬编码,但我认为这更好地说明了这一点。
输出结果是这样的。
PRE MALLOC: L
80613b0
80613b0
1 80613b8
MALLOC后:M
那么这两个地址没有重叠,或者有什么奇怪的事情,但是第一个数组的第一个字符是递增的?如果我忽略了一些愚蠢的事情,我很抱歉。但我想不出任何原因为什么会发生这种情况。
有什么想法吗?
谢谢,
对于某些上下文,这里有更多的代码。
int lcv;
int numargs;
int numchars;
int offset;
int bool;
TCommand* ret_val;
char** tmp;
ret_val = (TCommand*) malloc ( sizeof (TCommand) );
ret_val->cmd = NULL;
ret_val->args = NULL;
/* CMD */
lcv = 0;
numargs = 0;
numchars = 0;
offset = 0;
/* Remove initial whitespace */
while (input[offset] == ' ')
{
++offset;
}
lcv = offset;
/* Loop through command string */
while ( input[lcv] != ' ' && input[lcv] != 0 && input[lcv] != '&')
{
++numchars;
++lcv;
}
ret_val->cmd = (char*) malloc ( (numchars+1) * sizeof(char));
/* Copy to command string */
memcpy (ret_val->cmd, &(input[offset]), (numchars * sizeof (char)));
ret_val->cmd[numchars] = 0;
offset += numchars;
/* Copy command string into first argument */
ret_val->args = (char**) malloc ( sizeof (char*));
memcpy (ret_val->args[numargs++],ret_val->cmd, (numchars+1) * sizeof(char));
bool = 1;
while ( bool )
{
/* Remove initial whitespace */
while (input[offset] == ' ')
{
++offset;
}
lcv = offset;
if ( input[lcv] == 0 )
{
bool = 0;
}
else
{
++numargs;
tmp = (char**) realloc (ret_val->args, numargs * sizeof (char*));
ret_val->args = tmp;
numchars = 0;
while ( input[lcv] != ' ' && input[lcv] != 0 &&
input[lcv] != '&')
{
++numchars;
++lcv;
}
printf ("PRE MALLOC: %c\n", ret_val->args[0][0]);
printf ("[0] %p\n", ret_val->args[0]);
ret_val->args[1] = (char*) malloc ((2) * sizeof (char));
printf ("[0] %p\n", ret_val->args[0]);
printf ("[1] %p\n", ret_val->args[1]);
printf ("POST MALLOC: %c\n", ret_val->args[0][0]);
fflush(stdout);
memcpy (ret_val->args[numargs-1],&(input[offset]),numchars * sizeof (char));
ret_val->args[numargs-1][numchars] = 0;
offset += numchars;
}
}发布于 2010-12-13 10:25:58
这段代码:
/* Copy command string into first argument */
ret_val->args = (char**) malloc ( 2 * sizeof (char*));
memcpy (ret_val->args[numargs++],ret_val->cmd, (numchars+1) * sizeof(char));通过未初始化的指针ret_val->args[0]进行复制。尝试:
/* Copy command string into first argument */
ret_val->args = malloc(2 * sizeof ret_val->args[0]);
ret_val->args[numargs] = malloc(numchars + 1);
memcpy(ret_val->args[numargs++], ret_val->cmd, numchars + 1);(请注意,语言将sizeof(char)定义为1)。
发布于 2010-12-13 10:08:01
问题不在于您显示的片段,而在于您没有显示的代码中的某个地方。
因此,您需要从头开始构建示例-显示结构声明、内存管理和对结构所做的复制。
发布于 2010-12-13 10:18:13
这听起来像是堆损坏的典型例子。
您所看到的很可能是malloc()调用用返回值覆盖了args[0]所指向的字符串的结果。如果args数组实际上没有足够的空间容纳第二个参数,就会发生这种情况。通过写入args[1],您将覆盖argv[0]所指向的字符串的内容,我怀疑您在分配args数组后立即使用strdup()调用或类似方法分配了该字符串的内容。
由于堆向上增长,并且假设没有介入的free()调用,通过超越动态分配的数组的界限,增加了扰乱随后立即分配的区域的机会。
我将大胆猜测,并建议您通过打印args调用的参数并检查其返回值来检查为realloc()数组分配的大小。
编辑:
显然不是在这种情况下。似乎argv[0]指针实际上可能是未初始化的,而不会导致分段错误。有趣的是。
https://stackoverflow.com/questions/4425191
复制相似问题