简体   繁体   English

返回一个char指针数组

[英]Returning an array of char pointers

I'm trying to return an array of char* 's to a function. 我正在尝试将char*的数组返回给函数。 I've simplified my code to a test case that clones a char array that instead of containing chars holds pointers to those chars. 我已经将我的代码简化为一个测试用例,该测试用例克隆了一个char数组,而不是包含字符,而是包含指向这些字符的指针。

/*
 * 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;
}

A couple of warnings aside, this is what the compiler has to say about this code snippet: 抛开一些警告,这就是编译器对这段代码的看法:

invalid initializer (at char* cPTest[] = makePointerCopy(cTest); ) 初始化程序无效(在char* cPTest[] = makePointerCopy(cTest);

Why does this happen? 为什么会这样?

Because makePointerCopy returns a char* , not a char*[] . 因为makePointerCopy返回char* ,而不是char*[]

You should be able to change that line to: 您应该能够将该行更改为:

char* cPTest = makePointerCopy(cTest);

More specifically, the reason that you get THAT error message, rather than something about types, is that array initializers are required to be compile-time constants. 更具体地说,你得到THAT错误消息而不是类型的原因是数组初始化器需要是编译时常量。

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

Even if the declaration is not at file scope, it would be illegal in both C90 and C99. 即使声明不在文件范围内,它在C90和C99都是非法的。 C90 demands compile-time constant initializers for automatic and register arrays. C90要求自动和寄存器阵列的编译时常量初始化器。 And both C90 and C99 require a character array to be initialized with a) a string literal, or b) a brace-enclosed initializer list. 并且C90和C99都需要使用a)字符串文字初始化字符数组,或者b)括号括起的初始化列表。

Still, the type mismatch is the actual problem here. 但是,类型不匹配是这里的实际问题。

At that line, you are trying to assign a char* to a char* array. 在该行,您尝试将char *分配给char *数组。 Simply put, they are different types. 简单地说,它们是不同的类型。

You need to return a char ** or a char *[] . 您需要返回char **char *[]

In particular if you want makePointerCopy to return "an array of char* then you need to actually return such an array. Right now you're returning a pointer to a char , or " char* ". 特别是如果你想让makePointerCopy返回“ char*数组,那么你需要实际返回这样一个数组。现在你要返回一个指向char的指针,或者” char* “。

The line of code in question is attempting to assign the result of makePointerCopy , which returns a char* to a char*[] . 有问题的代码行试图分配makePointerCopy的结果,该结果将char*返回给char*[] While this is technically okay in C, and the compiler will still produce a result, the compiler is basically informing you that what it produces may not in fact execute as you expect. 虽然这在技术上可以在C中使用,并且编译器仍然会产生结果,但编译器基本上会告诉您它生成的内容实际上可能并不像您期望的那样执行。

Because your function returns char* while you're assigning it to char*[] . 因为您的函数在将其分配给char*[]返回char* C might have a pretty weak type system but some things shouldn't be done :-) C可能有一个非常弱的类型系统,但有些事情不应该做:-)

Let's start with the warning. 让我们从警告开始。 You declared: 你宣布:

char* cPTest[]

in English: " cPTest is an array of pointers to char " 英文:“ cPTest是一个指向char的指针数组

and

char* makePointerCopy(char cIn[]);

in English: " makePointerCopy() takes an array of chars and returns a pointer to char " 英文:“ makePointerCopy()接受一个字符数组并返回指向char的指针

So you are trying to assign a " pointer to char " to " an array of pointers to chars ". 因此,您尝试将“ 指向char的指针 ”分配给“ 指向字符 的指针数组 ”。 Can you see the problem? 你能看到问题吗? I would suggest to carefully check the types before doing assignments. 我建议在完成作业之前仔细检查类型。

That said, what you really want is to declare makePointerCopy() to return a "pointer to a pointer to char": 也就是说,你真正想要的是声明makePointerCopy()返回一个“指向char的指针”:

char **makePointerCopy(char cIn[]);

because, in the end, you will return the pointer to the first element of the return array. 因为,最后,您将返回指向返回数组的第一个元素的指针。

Another important point: you declared you "cOut" as local variable to a function. 另一个重点:你声明你“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
}

Remember that local variables are automatically made invalid once the function terminates. 请记住,一旦函数终止,局部变量将自动变为无效。 To "preserve" it you can declare it static : 要“保留”它,你可以声明它是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 
}

Note that you must be well disciplined when return such type of values. 请注意,返回此类值时,您必须严格遵守规则。

As an alternative you can allocate the space you need with malloc() as long as you will remember to free() it when you don't need it anymore. 作为替代方案,您可以使用malloc()分配所需的空间,只要您记得在不再需要它时free()它。

All of the other answers are correct, but there seem to be quite a lot of other problems with your code: 所有其他答案都是正确的,但您的代码似乎存在很多其他问题:

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

I believe you think sizeof(cIn) returns the amount of memory occupied by the elements in the cIn array. 我相信你认为sizeof(cIn)返回cIn数组中元素占用的内存量。 That is incorrect. 那是不对的。 In this case, sizeof(cIn) will return the size of a pointer on your system, usually 4 or 8 bytes. 在这种情况下,sizeof(cIn)将返回系统上指针的大小,通常为4或8个字节。 sizeof(cIn[0]) will return the size of a character, which is 1 byte. sizeof(cIn [0])将返回一个字符的大小,即1个字节。 There is generally no way to discover the size of an array in C, so I'm afraid you'll have to pass that size to your function. 通常没有办法在C中发现数组的大小,所以我担心你必须将这个大小传递给你的函数。

Also keep in mind that makePointerCopy returns a pointer to a statically allocated block of memory. 还要记住,makePointerCopy返回一个指向静态分配的内存块的指针。 That memory basically is a local variable of makePointerCopy, and will be released when makePointerCopy has finished doing it's job. 该内存基本上是makePointerCopy的局部变量,并在makePointerCopy完成它的工作时释放。 In other words, makePointerCopy will return a pointer to invalid memory. 换句话说,makePointerCopy将返回指向无效内存的指针。

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

char *是一个指向单个char的指针,因为你需要char ** ,它是一个指向数组或char *的指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM