C语言 代码第一次迭代后的意外输出



我真的不知道下面的事情是怎么发生的。下面是代码:

while(1)
{
    char** line = read_command();
    char* command = line[0];
    char** parameters = malloc(100);
    int i;
    for(i = 0; i < pNum; i++) // pNum is a global var containing the number of words read from read_command()
    {
        parameters[i] = line[i];
        printf("%i: %s", i, parameters[i]);
    }
    printf("%sn", parameters[0]);
    parameters[0] = "/usr/bin/";
    strcat(parameters[0], command);
    printf("%sn", command);
    printf("%sn", parameters[0]);
    if(fork() != 0)
        waitpid(1, &status, 0);
    else
        execve(parameters[0], parameters, NULL);
}

read_command()返回一个char**,它基本上是输入的字符串的一个"数组",每个char*包含一个单词。例如,如果我输入"hello people of earth",结果将是["hello","people","of","earth"]。这个函数总是有效的。

在第一次迭代时,一切都像预期的那样工作。例如,当我输入"date"时,输出如下所示:

0: date
date
date
/usr/bin/date
and then the date is displayed

但是在第二次迭代时,如果我再次使用"date"作为输入,输出如下:

0:date
edate 
/usr/bin/datedate 
and the date command is not issued

第二个printf语句总是在第一次迭代后打印"e",即使我打印一个像"hello"这样的常量字符串。然后参数[0]不知何故有2个"日期",尽管命令指针只有1个"日期"。

在第三次迭代之后,程序不再等待用户输入,它只是不停地循环并显示"PM: warning, process table is full!"

什么可能导致这个?

我在MINIX 3.1.0中使用cc编译器为C

工作

编辑:read_command ():

char* line = malloc(), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;
int currPos = 0;
int currParam = 0;
int i;
char** parameters = malloc(100);
if(line == NULL)
    return NULL;
while(1)
{
    c = fgetc(stdin);
    if(c == EOF) || c == 'n')
        break;
    if(--len == 0)
    {
        char* linen = realloc(linep, lenmax *= 2);
        len = lenmax;
        if(linen == NULL)
        {
            free(linep);
            return NULL;
        }
        line = linen + (line - linep);
        linep = linen;
    }
    if((*line++ = c) == 'n')
        break;
}
*line = ''; // everything up to this point i got from this link: http://stackoverflow.com/a/314422/509914
 parameters[currentParam] = malloc(100);
for(i = 0; i < strlen(linep); i++);
{
    if(isspace(linep[i]) || line[i] == EOF)
    {
        parameters[currParam][currPos] = ';
        currPos = 0;
        parameters[++currParam] = malloc(100);
    }
    else
        parameters[currParam][currPos++] = line[i];
}
parameters[currParam][currPos] = '';
pNum = currParam + 1;
return parameters;

有趣的是,那些通过阅读著名的资源来学习的人,比如经过几十年考验和测试的K&R,往往比那些不这样做的人更少出现这些问题。

char** parameters = malloc(100);试图分配100 字节realloc也有类似的行为,所以我就不再提这个了。也许你的意思是分配100批char * ?分配pNum批次char *: char **parameters = malloc(pNum * sizeof *parameters);更有意义……char* linen = realloc(linep, (lenmax *= 2) * sizeof *linep);

strcat不分配内存;分配内存的函数只有malloccallocrealloc

当你调用strcat(foo, bar);时,你要求strcatbar所指向的字符串附加到foo所指向的字符串的末尾。在您的代码中,您试图修改字符串字面值。未定义的行为,通常是段错误。

甚至你修改的尝试都是错误的。在parameters[0] = "/usr/bin/";中,您不会将字符串复制到parameters[0];您将分配parameters[0]指向字符串(如前所述,它通常位于不可变内存中)。您确实需要通过创建MCVE来缩小未定义行为的来源…

read_command()函数char* line = malloc(), * linep = line;的第一行中,您调用了malloc而没有提供参数。这违反了约束。您的编译器应该向您发出一个错误。也许你忘记了#include <stdlib.h>,所以malloc丢失了它的原型?请提供一个MCVE,这样我们就不用这样猜测了。

if(c == EOF) || c == 'n')有另一个约束违反…即使我们填补空白为您生成MCVE(我们不应该这样做,因为这是您的工作您正在向我们寻求帮助),该代码也无法编译。也许这就是导致你撞车的原因?总是检查编译器给你的消息。不要忽视警告……一定不要忽略错误信息。

我比较了你声称来自这个答案的代码,它是相当不同的。首先,这个答案的代码可以编译。然而,这是你与那些试图帮助你的人建立信任的方式吗?通过撒谎吗?

你不需要这么多的动态分配,通常我会特意解释你如何才能以最好的方式做到这一点,但是谎言让我很反感。我还有一点要说明:确保parameters以空指针结束(类似于字符串以空字符结束),因为这是手册所要求的。

相关内容

  • 没有找到相关文章

最新更新