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

将数组的内存分配给char指针,c,pointers,multidimensional-array,memory-management,C,Pointers,Multidimensional Array,Memory Management,下面的代码在为最后一个参数分配内存时出现分段错误。我做错了什么?谢谢 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*)); c

下面的代码在为最后一个参数分配内存时出现分段错误。我做错了什么?谢谢

    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++;
    }
int n_args=0,i=0;
而(行[i]!='\0')
{
if(isspace(第[i++]行)
n_args++;
}
对于(i=0;i

谢谢。

for
循环之后,您不会重置
i
的值,因此当到达底部块时
i
等于
n_args
。此时尝试访问
命令[i]
将访问未初始化的内存和SEGFULTS


这里真正的教训是在没有充分理由的情况下不要以这种方式重用变量。如果你使用的是除<代码> > <>代码>中的代码> <代码> >循环> ./p> < p>对于包含由单个空间分隔的两个参数的行,NyARG将是1而不是2。这可能不是你想要的

for (i = 0; i < n_args; i++)
        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出现在空指针上。

我认为这里发生了一些有趣的事情(如果我读对了的话)

该区块:

for (i = 0; i < n_args; i++)
    command = malloc (n_args * sizeof(char*));
无需反复重新分配
命令


至于seg故障,可能是因为您正在使用
i
变量,而没有先将其重置为零。

您正在丢弃第一个参数?这是故意的吗?万一不是

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索引,它超出了代码中分配的数组。

请尝试正确安排此循环:

 while (arg != NULL)
    {
        arg = strtok(NULL, " \n");
            command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
        strcpy(command[i], arg);
        i++;
    }
“arg=strtok…”行有两个错误:

  • 跳过第一个参数
  • 不检查返回代码,因此如果arg==NULL,则strlen(arg)将出错
  • 改为这样做:

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

    很难弄清楚你想做什么

    看起来您正在查看命令行中的空格数,以查看有多少命令行参数。所有命令行参数都是单个字符吗? malloc只为每个arg保留了足够的空间来容纳一个字符

    如果您的参数仅为每个字符一个字符:

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

    我添加它作为评论,不想重新编辑我的答案。小诡辩,重复使用变量用于不同的目的是不好的,你在3个不同的地方重复使用i,在其中的2个地方它索引了相同的东西,所以在我看来没问题。第一个用法不同,索引在
    上,语义不同,我会使用另一个变量。它不会对编译器造成任何影响,但是如果变量在中间没有改变角色,它将更容易被读取。在结束时放置<代码> Strutok(null ),避免跳过第一个参数。
     while (arg != NULL)
        {
            command[i] = malloc ( (strlen(arg)+1) * sizeof(char) );
            strcpy(command[i], arg);
            i++;
            arg = strtok(NULL, " \n");
        }
    
    command = malloc(strlen(line));
    i = 0;
    j = 0;
    while(line[j]) {
       if(!isspace(line[j])){
          command[i++] = line[j];
       }
       j++;
    }