将数组的内存分配给char指针

时间:2010-05-25 18:29:50

标签: c pointers multidimensional-array memory-management

以下代码在为最后一个arg分配内存时给出了分段错误。我究竟做错了什么?感谢。

    int n_args = 0, i = 0;
    while (line[i] != '\0')
    {
        if (isspace(line[i++]))
            n_args++;
    }

    for (i = 0; i < n_args; i++)
        command = malloc (n_args * sizeof(char*));

    char* arg = NULL;
    arg = strtok(line, " \n");
    while (arg != NULL)
    {
        arg = strtok(NULL, " \n");
            command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
        strcpy(command[i], arg);
        i++;
    }

感谢。

7 个答案:

答案 0 :(得分:4)

i循环后,您不会重置for的值,因此当您到达底部块时,i等于n_args。此时尝试访问command[i]可访问未初始化的内存和段错误。

这里真正的教训不是没有充分理由以这种方式重用变量。如果您在中间i循环中使用for以外的内容,则代码将更加强大且更易于阅读。

答案 1 :(得分:2)

for (i = 0; i < n_args; i++)
        command = malloc (n_args * sizeof(char*));

应该只是

command = malloc (n_args * sizeof(char*))

因为你只想分配一个n_args元素数组,并且

while (arg != NULL)
    {
        arg = strtok(NULL, " \n");
        command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
        strcpy(command[i], arg);
        i++;
    }

应该成为:

arg = strtok(NULL, " \n");
while (arg != NULL) {
    command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
    strcpy(command[i], arg);
    i++;
    arg = strtok(NULL, " \n");
}

避免空指针上的strlen。

答案 2 :(得分:0)

对于包含由单个空格分隔的两个参数的行,n_args将为1而不是2.这可能不是您想要的。

答案 3 :(得分:0)

我认为你在这里有一些有趣的事情(如果我正确地读到这个)。

这个区块:

for (i = 0; i < n_args; i++)
    command = malloc (n_args * sizeof(char*));

应该是这样的:

    command = malloc (n_args * sizeof(char*));

无需一遍又一遍地重新分配command

至于seg故障,可能是因为你重新使用i变量而不是先将它重置为零。

答案 4 :(得分:0)

你扔掉了你的第一个arg?这是故意的吗?如果它不是

int n_args = 1;     /* We need one element more than spaces */
int i = 0;
while (line[i])
{
    if (isspace(line[i++]))
        n_args++;
}

command = malloc (n_args * sizeof(char*));

char* arg = NULL;
arg = strtok(line, " \n");
i = 0;        /***** You forgot to reset that value, that was your segfault !!! */
while (arg)
{
    command[i++] = strdup(arg);  /* It does your malloc/strlen/strcpy */
    arg = strtok(NULL, " \n");
}

您忘记重置您的i索引,该索引在您的代码中到达分配的数组之外。

答案 5 :(得分:0)

尝试正确安排此循环:

 while (arg != NULL)
    {
        arg = strtok(NULL, " \n");
            command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
        strcpy(command[i], arg);
        i++;
    }

“arg = strtok ...”这两行有两件事:

  1. 跳过第一个参数。
  2. 不检查返回码,所以如果arg == NULL则strlen(arg)将为SEGFAULT。
  3. 请改为:

     while (arg != NULL)
        {
            command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
            strcpy(command[i], arg);
            i++;
            arg = strtok(NULL, " \n");
        }
    

答案 6 :(得分:0)

很难弄清楚你想要做什么。

看起来您正在查看命令行中的空格数,以查看您拥有的命令行参数的数量。你的所有命令行args都是一个字符吗? malloc只为每个arg一个字符保留足够的空间。

如果你的args只是一个字符:

command = malloc(strlen(line));
i = 0;
j = 0;
while(line[j]) {
   if(!isspace(line[j])){
      command[i++] = line[j];
   }
   j++;
}