C string declaration
c, string
Solution
char* str1="string";
This makes `str1` a pointer; it points to the first character of the string literal. You should define it as `const`, because you're not allowed to modify a string literal:
const char *str1 = "string";
...
char str2[7]="string";
This makes `str2` an array of `char` (not a pointer), and copies the contents of the string literal into it. There's no need to define it as `const`; the array itself is writable. You can also omit the size and let it be determined by the initializer:
char str2[] = "string";
Then `sizeof str2 == 7` (6 bytes for `"string"` plus 1 for the terminating `'\0'`).
This:
char* str3=(char)malloc(sizeof(char)*7);
is written incorrectly, and it shouldn't even compile; at the very least, you should have gotten a warning from your compiler. You're casting the result of `malloc()` to type `char`. You should be converting it to `char*`:
char *str3 = (char*)malloc(sizeof(char) * 7);
But the cast is unnecessary, and can mask errors in some cases; see question 7.7 and following in the comp.lang.c FAQ:
char *str3 = malloc(sizeof(char) * 7);
But `sizeof(char)` is 1 by definition, so you can just write:
char *str3 = malloc(7);
`malloc()` allocates memory, but it doesn't initialize it, so if you try to print the string that `str3` points to, you'll get garbage -- or even a run-time crash if the allocated space doesn't happen to contain a terminating null character `'\0'`. You can initialize it with `strcpy()`, for example:
char *str3 = malloc(7);
if (str3 == NULL) {
fprintf(stderr, "malloc failed\n");
exit(EXIT_FAILURE);
}
strcpy(str3, "string");
You have to be very careful that the data you're copying is no bigger than the allocated space. (No, `strncpy() is not the answer to this problem.)
`void main()` is incorrect; it should be `int main(void)`. If your textbook told you to use `void main()` find a better textbook; its author doesn't know C very well.
And you need appropriate `#include` directives for any library functions you're using: `<stdio.h>` for `printf()`, `<stdlib.h>` for `exit()` and `malloc()`, and `<string.h>` for `strcpy()`. The documentation for each function should tell you which header to include.
I know this is a lot to absorb; don't expect to understand it all right away.
I mentioned the comp.lang.c FAQ; it's an excellent resource, particularly section 6, which discusses arrays and pointers and the often confusing relationship between them.
As for your question 3, how to return a string from a C function, that turns out to be surprisingly complicated because of the way C does memory allocation (basically it leaves to to manage it yourself). You can't safely return a pointer to a local variable, because the variable ceases to exist when the function returns, leaving the caller with a dangling pointer, so returning your `str2` is dangerous. Returning a string literal is ok, since that corresponds to an anonymous array that exists for the entire execution of your program. You can declare an array with `static` and return a pointer to it, or you can use `malloc()` (which is the most flexible approach, but it means the caller needs to `free()` the memory), or you can require the caller to pass in a pointer to a buffer into which your function will copy the result.
Some languages let you build a string value and simply return it from a function. C, as you're now discovering, is not one of those languages.
Problem
I am confused about some basics in C string declaration. I tried out the following code and I noticed some difference: ``` char* foo(){ char* str1="string"; char str2[7]="string"; char* str3=(char)malloc(sizeof(char)*7); return str1; /* OR: return str2; */ /* OR: return str3; */ } void main() { printf("%s",foo()); return 0; } ``` I made foo() return str1/2/3 one at a time, and tried to print the result in the main. str2 returned something weird, but str1 and str3 returned the actual "string". 1.Now, what's the difference between the three declarations? I think the reason why str2 didn't work is because it is declared as a local variable, is that correct? 2.Then what about str1? If the result remains after the foo() ended, wouldn't that cause memory leak? 3.I'm simply trying to write a function that returns a string in C, and use the value returned by that function for other stuff, which str declaration above should I use? Thanks in advance!