二维char **数组中的strcpy()分段错误

时间:2013-04-12 15:04:56

标签: c segmentation-fault strcpy

我正在编写一个shell,它抓取输入并将其存储在字符串(char *)数组中。要启用像流水线操作这样的UNIX操作,我希望能够编写像

这样的命令
echo this | function more | function2

为此,我在while循环中收集命令及其参数,并尝试将参数数组的所有内容复制到一个新的二维数组中,该数组包含整个命令行,例如: “ls -f -a”。 到目前为止,这是有效的,但是,当我在命令行中找到“|”时,我试图重置循环,忽略“|”,并开始一个新的循环在找到'\0'之前做同样的事情,这标志着原始输入的结束:

char* arguments[MAXARGS]; // holds argument components, e.g. "ls" or "-f"
char** arg_collection[MAXARGS][MAXARGS]; // supposed to hold command lines, e.g. "ls -f -a"
argc_current = 0; // iterator for the loop, counts arguments
col_iterator = 0; // iterator for amount of command lines
int sentinel = 1; // sentinel value for while loop
...

while(sentinel)
{
    arguments[argc_current] = (char*) malloc (sizeof(word)); // word is defined, just not listed on here - refers to the currently read command / argument
     strcpy(arguments[argc_current], word); // copy current word into arguments

    if(tokens[argc_current] == TOKEN_TERMINATOR || tokens[argc_curernt] == TOKEN_NULL)
    {
       sentinel = 0; // tokens holds information about the type of word, e.g. if it is '\0'
    }

    if(tokens[argc_current] == T_BAR) // if the word is "|"
    {
       for(i = 0; i < argc_current; i++)
       {
          strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection
       }

       col_iterator++; // increment command line counter
       argc_current = 0; // reset argument counter, restart the loop
    }

    else
    {
        arg_current++; // increment current argument counter
    }
}

evaluating arguments here..

第一个循环工作正常,例如如果我输入

echo this | echo more |

它会填充arg_collection[0][0]arg_collection[0][1],因此我会收到“echo this”。 然而,在将col_iterator增加到1之后,在注意到第二个“|”时调用strcpy时,我以分段错误的形式撞到了一堵砖墙。为什么呢?

2 个答案:

答案 0 :(得分:2)

看起来wordchar*。如果是这样,你应该改变

arguments[argc_current] = (char*) malloc (sizeof(word));

arguments[argc_current] = malloc(strlen(word)+1);

sizeof(word)将为您提供指针变量的大小,而不是它指向的数据的大小。 strlen会告诉您word中的字符数。 +1终结符需要'\0'

答案 1 :(得分:0)

首先,您应该在使用之前分配arg_collection。 (因为你没有提供整个代码,我假设你不这样做。)

然后你在线上取消引用你的arg_collection两次:

strcpy(arg_collection[col_iterator][i], arguments[i]); // copy argument list into collection

什么时候必须

strcpy(arg_collection[col_iterator], arguments[i]); 

也就是说,当它只是一个字符时,你将arg_collection中字符串col_iterator的索引i处的char视为char *。