Returning an array of char pointers

I am trying to return a char* array to a function. I simplified my code for a test case that clones a char array that, instead of containing characters, contains pointers to those characters.

 /* * 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 few warnings aside, this is what the compiler should say about this piece of code:

invalid initializer (at char* cPTest[] = makePointerCopy(cTest); )

Why is this happening?

+4
source share
8 answers

Because makePointerCopy returns a char* , not a char*[] .

You should be able to change this line to:

 char* cPTest = makePointerCopy(cTest); 

More specifically, the reason you get a THAT error message rather than something about types is because array initializers must be compile-time constants.

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

Even if the declaration is not in the scale file, it would be illegal as in C90 and C99. C90 requires compile-time constant initializers to automatically and register arrays. And both C90 and C99 require that the character array be initialized a) by a string literal, or b) an initializer, enclosed in parentheses, a list.

However, type mismatching is the real issue here.

+5
source

On this line, you are trying to assign the char * array to the char * array. Simply put, they are different.

+3
source

You need to return char ** or char *[] .

In particular, if you want makePointerCopy return a " char* array, then you need to actually return such an array. Right now you are returning a pointer to char or" char* ".

The line of code in question is trying to appropriate the result of makePointerCopy , which returns char* in char*[] . Although this is technically good in C, and the compiler will still produce a result, the compiler basically informs you that what it produces cannot actually be executed as you expect.

+2
source

Since your function returns char* , while you assign it to char*[] . C may have a rather weak type system, but some things should not be done :-)

+2
source

Let's start with a warning. You stated:

 char* cPTest[] 

in English: " cPTest is an array of pointers to char"

and

 char* makePointerCopy(char cIn[]); 

in English: " makePointerCopy() takes an array of characters and returns a pointer to char"

So you are trying to assign a "pointer to char" to an "array of pointers to characters". Do you see the problem? I would suggest carefully checking types before completing assignments.

This means that you really want to declare makePointerCopy() to return a "pointer to a pointer to a char":

 char **makePointerCopy(char cIn[]); 

because at the end you will return a pointer to the first element of the returned array.

Another important point: you declared "cOut" a local variable for the function.

 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 automatically become invalid after the function finishes. To β€œsave” it, you can declare it 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 returning this type of value.

Alternatively, you can allocate the space you need with malloc() until you remember free() it when you no longer need it.

+2
source

All other answers are correct, but there seem to be many other problems in your code:

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

I think you think that sizeof (cIn) returns the amount of memory occupied by the elements in the cIn array. This is not true. In this case, sizeof (cIn) will return the size of the pointer on your system, usually 4 or 8 bytes. sizeof (cIn [0]) will return the size of the character, which is 1 byte. Generally, there is no way to find out the size of an array in C, so I'm afraid that you will have to pass this size to your function.

Also keep in mind that makePointerCopy returns a pointer to a statically allocated block of memory. This memory is basically a local variable makePointerCopy and will be released when makePointerCopy finishes this task. In other words, makePointerCopy will return a pointer to invalid memory.

+1
source

The function returns char * not a char [] *.

0
source

char * is a pointer to a single char, where you need char ** , which is a pointer to an array or char *

0
source

Source: https://habr.com/ru/post/1299118/


All Articles