将一个字符串数组作为参数传递给C中的函数

时间:2009-01-28 01:06:35

标签: c arrays pointers parameters segmentation-fault

我想要一个接收字符串的简单函数,并在解析后返回一个字符串数组。所以,这是我的功能签名:

int parse(const char *foo, char **sep_foo, int *sep_foo_qty) {
    int i;
    char *token;
    ...
    strcpy(sep_foo[i], token); /* sf here */
    ...
}

然后我称之为:

char sep_foo[MAX_QTY][MAX_STRING_LENGTH];
char foo[MAX_STRING_LENGTH];
int sep_foo_qty, error;

...

error = parse(foo, sep_foo, &sep_foo_qyt);

...

这样我在编译时会收到警告:

warning: passing argument 2 of 'parse' from incompatible pointer type

然后在/ * sf标记为* /

的行中执行期间出现分段错误

我的C代码有什么问题?

提前致谢

4 个答案:

答案 0 :(得分:28)

警告完全正确。你的函数想要一个指针数组。你给它一个数组数组。

预期:

 sep_foo:
 +------+       +-----+
 |char**|--> 0: |char*|-->"string1"
 +------+       +-----+
             1: |char*|-->"string2"
                +-----+
*sep_foo_qty-1: |...  |
                +-----+

您提供的内容:

           sep_foo:
           +--------------------------------+
        0: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
        1: | char[MAX_STRING_LENGTH]        |
           +--------------------------------+
MAX_QTY-1: | ...                            |
           +--------------------------------+

包含X类型元素的数组可以“衰减”为指针指向XX*。但是X的值不允许在该转换中更改。仅允许一次衰减操作。你需要它发生两次。在您的情况下,X是数组 - MAX_STRING_LENGTH - 字符。该函数希望X成为指向char的指针。由于它们不相同,编译器会发出警告。我有点惊讶它只是一个警告,因为编译器允许发生的事情没有任何好处。

在您的函数中,您可以编写以下代码:

char* y = NULL;
*sep_foo = y;

这是合法代码,因为sep_foochar**,因此*sep_foochar*y也是如此。你可以分配它们。但是,根据您的尝试,*sep_foo <{1}}它会指向一个char数组。实际上,您的代码将尝试执行此操作:

char*

您无法将指针分配到数组中,因此编译器会警告该调用不合适。

有两种方法可以解决这个问题:

  • 更改您在主叫方声明和分配char destination[MAX_STRING_LENGTH]; char* y = NULL; destination = y; 的方式,使其与函数预期接收的内容相匹配:

    sep_foo

    或等同于

    char** sep_foo = calloc(MAX_QTY, sizeof(char*));
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    
  • 更改函数的原型以接受您真正给出的内容:

    char* sep_foo[MAX_QTY];
    for (int i = 0; i < MAX_QTY; ++i)
      sep_foo[i] = malloc(MAX_STRING_LENGTH);
    

答案 1 :(得分:15)

参数2应为

char sep_foo[][MAX_STRING_LENGTH]

为了澄清,您正在传递一个指向parse()的指针并将其视为指向指针的指针。 C中的多维数组不是指针数组。它是数组变量指向的单个内存块。你不能两次取消引用它。

答案 2 :(得分:4)

sep_foo被定义为数组数组。换句话说,当您使用sep_foo时,它指向顺序内存的开头。这是一个模型:

(assume MAX_STRING_LENGTH = 16, MAX_QTY = 2)
sep_foo       = &&0000
sep_foo[0]    =  &0000
sep_foo[0][0] = *&0000 = 12
sep_foo[0][8] = *&0008 = 74
sep_foo[1]    =  &0010
sep_foo[1][0] = *&0010 = 12


0000  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

但是,您的函数需要一个指针数组(实际上是一个指向指针的指针)。这是建模的:

sep_foo_arg       =   &&0000
sep_foo_arg[0]    =  *&&0000 = &0010
sep_foo_arg[0][0] =  *&*&0000 = 12
sep_foo_arg[0][8] = *(&*&0000 + 8) = 74
sep_foo_arg[1]    =  *&&0002 = &0020
sep_foo_arg[1][0] = *&*&0000 = 12

0000  0010 0020  xxxx xxxx  xxxx xxxx  xxxx xxxx

0010  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE
0020  12 34 56 78  9A BC DE F0  74 10 25 89  63 AC DB FE

是的......语法对我的解释可能有点混乱......

无论如何,你可以通过告诉你的函数如何处理指向的指针来解决这个问题。特别是,您可能希望将其视为一个数组(一系列内存):

int parse(const char *foo, char (*sep_foo)[MAX_STRING_LENGTH], int *sep_foo_qty);

答案 3 :(得分:-2)

如果那是您的确切代码,那么我猜测段错误是因为您没有为解析函数中的char* token分配内存,然后在strcpy中使用它。< / p>