What is the difference between returning char * and char [] from a function?

Why does the first function return the string "Hello, World", but the second function does not return anything. I thought that the return value of both functions would be undefined, as they return data that is out of scope.

#include <stdio.h> // This successfully returns "Hello, World" char* function1() { char* string = "Hello, World!"; return string; } // This returns nothing char* function2() { char string[] = "Hello, World!"; return string; } int main() { char* foo1 = function1(); printf("%s\n", foo1); // Prints "Hello, World" printf("------------\n"); char* foo2 = function2(); // Prints nothing printf("%s\n", foo2); return 0; } 
+61
c string pointers
Sep 07 '17 at 7:38 on
source share
6 answers

the second function returns nothing

The string array in the second function:

 char string[] = "Hello, World!"; 

has automatic storage duration. This does not exist after the control flow returns from the function.

While string in the first function:

 char* string = "Hello, World!"; 

points to a literal string that has a static storage duration. This means that the string is returned after returning from the function. What you return from the function is a pointer to this literal string.

+62
Sep 07 '17 at 7:40
source share

The first thing you need to know about strings is that a string literal is an array of read-only characters with a lifetime of the full program. This means that they will never go out of scope, they will always exist during program execution.

What the first function ( function1 ) does, returns a pointer to the first element of such an array.

With the second function ( function2 ) everything is a little different. Here, the string variable is a local variable inside the function. Thus, it will go beyond and cease to exist after the function returns. With this function, you return a pointer to the first element of this array, but this pointer will immediately become invalid, as it will indicate that it no longer exists. Deploying it (which happens when you pass it to printf ) will result in undefined behavior .

+24
Sep 07 '17 at 7:41
source share

It is very important to remember that when encoding in C or other stacks is based on the fact that when a function returns, it (and all its local storage) has disappeared. This means that if you want someone else to see the results of your difficult actions, you must put it somewhere that will exist after your method stops working, and for this you need to understand where C stores the material And How.

You probably already know how an array works in C. This is just a memory address that is incremented by the size of the object, and you probably also know that C does not perform border checking, so if you want to access the 11th element out of ten elements of the array, no one will stop you, and while you are not trying to write anything, there will be no harm. You may not know that C extends this idea before it uses functions and variables. A function is just a region of memory on the stack that is loaded on demand, and the storage for its variables is simply shifted from this location. Your function returned a pointer to a local variable, namely the address of the place on the stack containing "H" "Hello World \ n \ 0", but when you called another function (print method) that contained memory that was reused by the print method, to do what he needs. You can see it easily enough (DO NOT DO IT IN THE PRODUCTION CODE !!!)

 char* foo2 = function2(); // Prints nothing ch = foo2[0]; // Do not do this in live code! printf("%s\n", foo2); // stack used by foo2 now used by print() printf("ch is %c\n", ch); // will have the value 'H'! 
+7
Sep 07 '17 at 11:20 on
source share

I thought the return value of both functions would be undefined, as they return data that goes beyond the scope.

No. This is not true.

In function1 you return a pointer to a string literal. A return pointer to a string literal is fine because string literals have a static storage duration. But this is not the case with an automatic local variable.

In function2 function2 string array is an automatic local variable and statement

 return string; 

returns a pointer to an automatic local variable. After the function returns, the string variable will no longer exist. Highlighting the return pointer will result in undefined behavior.

+5
Sep 07 '17 at 7:41
source share

I thought the return value of both functions would be undefined, as they return data that goes beyond the scope.

Both functions return a pointer. The scope of the referent is important.

In function1 referent is the string literal "Hello, World!" which has a static storage duration. string is a local variable that points to this string, and conceptually a copy of this pointer is returned (in practice, the compiler avoids unnecessarily copying the value).

In function2 conceptual referent is the local string array, which was automatically set (at compile time) to be large enough to contain a string literal (including the null terminator, of course), and was initialized with a copy of the string. The function will return a pointer to this array, except that the array has an automatic storage duration and, therefore, no longer exists after exiting the function (it really "goes beyond", in the more familiar terminology). Since this behavior is undefined, the compiler can do all kinds of things in practice .

Does this mean that all char* are static?

Again, you need to distinguish between pointer and referent. Pointers indicate data; they themselves do not "contain" data.

You have reached the point where you must correctly examine which arrays and pointers are actually in C - unfortunately this is a bit of a mess. The best recommendation I can offer is this , in Q & A format.

0
Sep 08 '17 at 6:02
source share

"Hello, World!" is a string literal that has a static storage duration, so the problem is elsewhere. Your first function returns a string value , which is great. The second function, however, returns the address of the local variable ( string same as &string[0] ), which leads to undefined behavior. Your second printf statement may not print anything, or "Hello, World!", Or something else. On my machine, the program just gets a segmentation error.

Always watch the messages printed to the compiler. For your example, gcc gives:

 file.c:12:12: warning: function returns address of local variable [-Wreturn-local-addr] return string; ^ 

which is pretty much self-evident.

0
Sep 08 '17 at 8:24 on
source share



All Articles