Return strings with const char * in C

I am trying to understand why the next line is being passed for my error line. I made this example from a much larger source that I have.

My question is: why should I not specifically allocate memory for the char array that contains my error message? I would think that I need to copy some memory for a string and use the err pointer to indicate the beginning of this memory.

Is it due to the fact that its a const char * or is it because I print to stderr?

Perhaps I am phrasing the question incorrectly, so the searches did not help me figure this out.

 const char * my_function(int a) { if (a != 1) return "a doesn't equal 1!" else return NULL; } int main(int a) { const char *err; err = my_function(a); if (err) fprintf(stderr, "Message = %s\n",err); return 1; return 0; } 
+4
source share
6 answers

All string literals are allocated at compile time. They are already in the read-only section in program memory when your program starts; they are not allocated at runtime. You can consider them as constant arrays of characters. And like any const variable, they remain valid throughout the execution of the program.

+6
source

String literals are allocated as const char arrays with static storage duration, so they live throughout the entire program life cycle. The area in which they are located does not matter - they always have a static storage duration.

This means that you can take your address (which happens implicitly if you return a string literal or store it in a const char * variable anywhere) without worrying about the lifetime of the resulting pointer. Storage for a string literal will never be used for anything else.

+2
source

You are returning a string literal. It is stored in static memory, but has an address, like any other line. So you can link to this address at any time. The problem is that if you try to change the string literal, which in my opinion is undefined.

+2
source

This is because the string is stored in the data section of your program. When you enter "a doesn't equal 1!" stands out , and this value is written to it.

You simply return a pointer to this piece of memory, and fprintf happy to read it.

+1
source

Note that your main() will always return 1.

 int main(int a) { const char *err; err = my_function(a); if (err) fprintf(stderr, "Message = %s\n",err); return 1; return 0; } 

return 1 is indented as if it were under if (err) , but it is not. Do you really have:

 int main(int a) { const char *err; err = my_function(a); if (err) fprintf(stderr, "Message = %s\n",err); return 1; return 0; # Never gets executed. } 

What would you like:

 int main(int a) { const char *err; err = my_function(a); if (err) { fprintf(stderr, "Message = %s\n",err); return 1; } return 0; } 

For this reason, I always use braces around my blocks, even if they are not strictly necessary.

+1
source

Do not be too optimistic. This is because the line in your routine is stored in a shared segment (read-only), and it can be returned after the procedure completes. If you define it as char str [] = "your string", you cannot return the value because it is "allocated" on the stack. The stack pointer resumes at the end of the subroutine.

0
source

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


All Articles