Can / Why does using char * instead of const char * in the inverse type cause failures?

I read somewhere that if you want the C / C ++ function to return an array of characters (unlike std :: string), you must return const char *, not char *. Executing the latter may cause the program to crash.

Can anyone explain if this is true or not? If true, why is char * returned from such a dangerous function? Thanks.

const char * my_function() { .... } void main(void) { char x[] = my_function(); } 
+6
c char const
source share
5 answers

If you have a function that returns "string literals", then it should return const char *. They should not be allocated on the malloc heap because they are compiled into a read-only section of the executable itself.

Example:

 const char* errstr(int err) { switch(err) { case 1: return "error 1"; case 2: return "error 2"; case 3: return "error 3"; case 255: return "error 255 to make this sparse so people don't ask me why I didn't use an array of const char*"; default: return "unknown error"; } } 
+14
source share

What you were told is not true.

Returning const char * can improve the semantics of the function (i.e., not messing with what I give you), but returning char * fine.

However, in any case, you must make sure that you return the char * or const char * that were allocated on the heap to my_function (i.e., allocated using malloc or new ), otherwise whenever my_function returned, the memory for [const] char * will be freed, and you will get access to an invalid pointer.

And finally, you must remember the free or delete [const] char * that were returned to you after you finished with it, or you will be a memory leak. Are C / C ++ such wonderful languages?

So in C you would have

 const char *my_function() { const char *my_str = (const char *)malloc(MY_STR_LEN + 1); // +1 for null terminator. /* ... */ return my_str; } int main() { const char *my_str = my_function(); /* ... */ free(my_str); /* ... */ return 0; } 
+11
source share

This is usually not a problem, but there are things to consider. This is usually a question of const-correctness, which means keeping track of what you can change and what you cannot.

If you return a double-quoted string, it is const char * and processes it, like everything else, is an invitation to trouble. Changing such a line is undefined behavior, but usually leads to the failure or change of this line, wherever it is mentioned.

If you return an array of characters on the stack (i.e. the local variable of the called function), it will leave and the pointer will not point to anything, in particular, possibly with bad results at some time.

If the called function returns what is already const char * , then a cast is required to change it to char * . In addition, if you are really going to change it, you must be sure that it is volatile. It is usually better to save it as const char * .

There is no problem with the return memory allocated using malloc() or new , but you have a ownership problem: what function should free() / delete when, and what will you do with the possible copy? This is where C ++ smart pointers shine.

+4
source share

If char * is allocated on the stack, you return a dangling pointer. Otherwise, if it matches the function prototype and the declaration matches the return value, you should be fine.

+2
source share

Simply changing the return code will not crash. However, if the string you are returning is static (for example, return "AString" ), you must return const char * to make sure that the compiler detects any attempt to modify this memory, which is likely to cause a failure. You can, of course, use throws, etc., to bypass compiler checks, but in this case you will have to work for the failure to occur.

+1
source share

All Articles