返回一个char指针数组

时间:2010-01-22 15:20:09

标签: c pointers

我正在尝试将char*的数组返回给函数。我已经将我的代码简化为一个测试用例,该测试用例克隆了一个char数组,而不是包含chars,而是持有指向这些字符的指针。

/*
 * code.c
 */
#include <stdio.h>

char* makePointerCopy(char cIn[]);

int main() {
    char cTest[] = {'c', 't', 's', 't'};
    char* cPTest[] = makePointerCopy(cTest);
    printf("%p %c", cPTest, *cPTest);
    fflush(stdout);
    return 0;
}

char* makePointerCopy(char cIn[]) {
    char* cOut[sizeof(cIn)/sizeof(cIn[0])];
    int iCntr;

    for (iCntr = 0; iCntr < sizeof(cIn)/sizeof(cIn[0]); iCntr++)
        cOut[iCntr] = cIn + iCntr;

    return cOut;
}

除了几个警告之外,这是编译器对此代码段的说法:

  

无效的初始值设定项(char* cPTest[] = makePointerCopy(cTest);

为什么会这样?

8 个答案:

答案 0 :(得分:5)

因为makePointerCopy会返回char*,而不是char*[]

您应该能够将该行更改为:

char* cPTest = makePointerCopy(cTest);

更具体地说,你得到THAT错误消息而不是类型的原因是数组初始化器需要是编译时常量。

来自http://bytes.com/topic/c/answers/215573-invalid-initializer

  

即使声明不在档案中   范围,在C90中都是违法的   和C99。 C90需要编译时   自动恒定初始化器   并注册数组。而C90和   C99需要一个字符数组   用a)字符串文字初始化,   或b)支架封闭的初始化器   列表。

但是,类型不匹配是这里的实际问题。

答案 1 :(得分:3)

在该行,您尝试将char *分配给char *数组。简单地说,它们是不同的类型。

答案 2 :(得分:2)

您需要返回char **char *[]

特别是如果你希望makePointerCopy返回“char*数组,那么你需要实际返回这样一个数组。现在你要返回指向char的指针,或“char*”。

有问题的代码行正在尝试分配makePointerCopy的结果,该结果会将char*返回给char*[]。虽然这在技术上可以在C中使用,并且编译器仍然会产生结果,但编译器基本上会告诉您它产生的内容实际上可能并不像您期望的那样执行。

答案 3 :(得分:2)

因为您的函数在将char*分配给char*[]时会返回{{1}}。 C可能有一个非常弱的类型系统,但有些事情不应该做: - )

答案 4 :(得分:2)

让我们从警告开始。你声明了:

char* cPTest[]

英文:“ cPTest是一个指向char的指针数组

char* makePointerCopy(char cIn[]);

英文:“ makePointerCopy()获取一组字符并返回指向char的指针

因此,您尝试将“指向char 的指针”分配给“指向字符的指针数组”。你能看到问题吗?我建议在完成作业之前仔细检查类型。

那就是说,你真正想要的是声明makePointerCopy()返回一个“指向char的指针”:

char **makePointerCopy(char cIn[]);

因为,最后,您将返回指向返回数组的第一个元素的指针。

另一个要点:你声明你“cOut”作为函数的局部变量。

char* makePointerCopy(char cIn[]) {
    char* cOut[sizeof(cIn)/sizeof(cIn[0])];

    ...  /* cOut can ONLY be used within the function! */

    return cOut;  // <-- The address returned point to a 
                  //     block of memory that is no longer valid
                  //     after the end of the function
}

请记住,一旦函数终止,局部变量将自动变为无效。要“保留”它,您可以声明它static

char* makePointerCopy(char cIn[]) {
    static char* cOut[sizeof(cIn)/sizeof(cIn[0])];

    ...  /* cOut will survive the end of the function */

    return cOut;  // <-- The address can be returned 
}

请注意,返回此类值时,您必须遵守纪律。

作为替代方案,您可以使用malloc()分配所需的空间,只要您不再需要free()就可以记住它。

答案 5 :(得分:1)

所有其他答案都是正确的,但您的代码似乎存在很多其他问题:

char* cOut[sizeof(cIn)/sizeof(cIn[0])];

我相信你认为sizeof(cIn)会返回cIn数组中元素占用的内存量。那是不对的。在这种情况下,sizeof(cIn)将返回系统上指针的大小,通常为4或8个字节。 sizeof(cIn [0])将返回一个字符的大小,即1个字节。通常无法在C中发现数组的大小,所以我担心你必须将这个大小传递给你的函数。

另请注意,makePointerCopy返回指向静态分配的内存块的指针。该内存基本上是makePointerCopy的局部变量,并在makePointerCopy完成它的工作时释放。换句话说,makePointerCopy将返回指向无效内存的指针。

答案 6 :(得分:0)

该函数返回char *而不是char [] *。

答案 7 :(得分:0)

char *是指向单个字符的指针,您需要char **,它是指向数组的指针或char *